Building Custom Commands
Learn to create reusable custom slash commands in Claude Code that automate repetitive workflows like running audits, writing tests, and generating boilerplate code.
Claude Code comes with built-in slash commands, but the real productivity boost comes from creating your own. Custom commands let you automate repetitive workflows — running security audits, writing tests to your team's conventions, generating boilerplate — with a single slash command.
Creating Your First Custom Command
Custom commands live in a specific folder structure inside your project:
Find the .claude folder
Locate the .claude directory in your project root (created when you first use Claude Code).
Create a commands directory
Inside .claude, create a new folder called commands.
Add a markdown file
Create a .md file whose filename becomes the command name. For example, audit.md creates the /audit command.
Restart Claude Code
Claude Code needs a restart to detect new command files.
Example: A Security Audit Command
Here is a practical custom command that audits your project dependencies for known vulnerabilities and automatically applies safe fixes:
1Run a security audit on this project:231. Run `npm audit` to identify vulnerable packages42. Run `npm audit fix` to apply safe updates53. Run the test suite to verify the updates did not break anything64. Report which packages were updated and any remaining vulnerabilitiesCommands with Dynamic Arguments
Custom commands become even more powerful with the $ARGUMENTS placeholder, which lets you pass dynamic input when invoking the command:
1Write comprehensive tests for: $ARGUMENTS23Testing conventions:4* Use Vitest with React Testing Library5* Place test files in a __tests__ directory alongside the source file6* Name test files as [filename].test.ts(x)7* Use @/ prefix for all imports89Coverage:10* Test happy paths and expected behavior11* Test edge cases and boundary conditions12* Test error states and error handlingYou can then invoke this command with any target:
1/write_tests the useAuth hook in src/hooks/use-auth.tsArguments are flexible
The $ARGUMENTS placeholder accepts any text — file paths, feature descriptions, bug reports, or style guidelines. Think of it as a free-form input that gives your command flexibility while enforcing consistent process.
Key Takeaways
- 01Custom commands live in .claude/commands/ as markdown files.
- 02The filename becomes the slash command name (audit.md → /audit).
- 03Use $ARGUMENTS to accept dynamic input when the command is invoked.
- 04Commands enforce consistency — every team member follows the same process.
- 05Restart Claude Code after adding new command files.