Creating Custom VS Code Snippets for Faster Development

If you find yourself repeatedly writing the same code patterns, VS Code snippets can help. Let's explore how to create custom snippets that will boost your productivity.

What are VS Code Snippets?

Snippets are reusable code templates that expand into larger blocks of code when triggered. Instead of manually typing common patterns, you can:

  1. Type a short prefix
  2. Press Tab
  3. Watch your snippet expand into a complete code block with customizable placeholders

Creating Your First Snippet

To get access to snippets:

  1. Open VS Code
  2. Navigate to File > Preferences > Configure User Snippets
    • Keyboard shortcut: Ctrl+Shift+P (Windows/Linux) or Cmd+Shift+P (Mac), then search for "Snippets"
  3. Select a language-specific file (e.g., "javascript.json" for JavaScript snippets)

Now let's review the structure of a snippet. There are a few main pieces:

  • prefix: The text you type to trigger the snippet
  • body: The actual code template (string or array of strings)
  • description: Helpful text shown in the IntelliSense menu

And here's what that looks like as code:

{
  "Snippet Name": {
    "prefix": "trigger",
    "body": [
      "Your snippet content",
      "goes here",
      "$1"
    ],
    "description": "What this snippet does"
  }
}

You can do more sophisticated things too with variables and placeholders which we will look at next.

Tab Stops and Placeholders

As you tab complete, you can used these numbered placeholders to configure where your cursor should stop next when you tab complete. Here's the syntax:

  • $1, $2, $3: Ordered tab stops. Eg. $1 is where your cursor will end up after the first tab and then $2.
  • ${1:default}: Tab stop with default text
  • $0: Final cursor position
  • Multiple occurrences of the same number synchronize changes

You can also access some built-in variables to use in your snippets:

$TM_FILENAME          Current file name
$TM_FILENAME_BASE     File name without extension
$CURRENT_YEAR         Current year (e.g., 2024)
$CURRENT_DATE         Current date (e.g., 10/31/2024)
$CLIPBOARD            Contents of your clipboard
$WORKSPACE_NAME       Current workspace name
$LINE_COMMENT         Line comment for current language

That's a lot of theory, but this stuff gets easy when you actually build stuff with it so here are some examples to get you going:

Snippet Examples

React TypeScript Component

{
  "React TypeScript Component": {
    "prefix": "rts",
    "body": [
      "import React from 'react'",
      "",
      "interface ${1:${TM_FILENAME_BASE}}Props {",
      "  ${2:// Props}",
      "}",
      "",
      "export const ${1:${TM_FILENAME_BASE}} = ({",
      "  ${3:// Destructured props}",
      "}: ${1:${TM_FILENAME_BASE}}Props): JSX.Element => {",
      "  return (",
      "    <div className=\"$4\">",
      "      $0",
      "    </div>",
      "  )",
      "}",
      "",
      "export default ${1:${TM_FILENAME_BASE}}",
      ""
    ],
    "description": "React TypeScript component with Props interface"
  }
}

Using this snippet:

  1. Create a new file (e.g., Button.tsx)
  2. Type rts and press Tab
  3. Component name automatically matches filename (e.g., "Button")
  4. Press Tab to move to props interface section
  5. Type your props (e.g., onClick: () => void)
  6. Press Tab to move to props destructuring
  7. Type the same props (e.g., onClick)
  8. Press Tab to add your className
  9. Press Tab one final time to move cursor inside the div

Example output after these steps:

import React from 'react'

interface ButtonProps {
  onClick: () => void
}

export const Button = ({
  onClick
}: ButtonProps): JSX.Element => {
  return (
    <div className="button-primary">
      {/* Cursor ends up here */}
    </div>
  )
}

export default Button

Enhanced Console Logger

{
  "Smart Console Log": {
    "prefix": "lgx",
    "body": [
      "console.log('[${TM_FILENAME_BASE}]', '${1:label}:', ${2:value});$0"
    ],
    "description": "Console log with filename context and value inspection"
  }
}

Using this snippet:

  1. Type lgx and press Tab
  2. Type the label for your log (e.g., "userData")
  3. Press Tab
  4. Type the variable name you want to log
  5. Press Tab to move to the next line

Example usage in a file named UserService.ts:

const user = await fetchUser(id);
lgx↹
// After typing "userData" and pressing Tab:
console.log('[UserService]', 'userData:', user);
// Console output: [UserService] userData: { id: 1, name: 'John' }

Error Handler with Async/Await

{
  "Try-Catch Async": {
    "prefix": "tca",
    "body": [
      "try {",
      "  ${1:// Async operation}",
      "} catch (error) {",
      "  console.error(",
      "    `[${TM_FILENAME_BASE}] ${2:Error message}:`,",
      "    error instanceof Error ? error.message : error",
      "  );",
      "  ${3:throw error;}$0",
      "}"
    ],
    "description": "Try-catch block with proper error handling"
  }
}

Using this snippet:

  1. Type tca and press Tab
  2. Type your async operation (e.g., const user = await fetchUser(id);)
  3. Press Tab
  4. Enter a descriptive error message (e.g., Failed to fetch user)
  5. Press Tab
  6. Modify or keep the error handling (e.g., change to throw new Error('User not found');)
  7. Press Tab to move to the next line

Example usage in UserService.ts:

async function getUser(id: string) {
  tca↹
  // After completing all steps:
  try {
    const user = await fetchUser(id);
  } catch (error) {
    console.error(
      `[UserService] Failed to fetch user:`,
      error instanceof Error ? error.message : error
    );
    throw new Error('User not found');
  }
}

[Rest of the document remains the same...]

Scope-Specific Snippets

When you were selecting how to create a snippet you might of noticed a lot of options. You can use these file options to scope your snippets to certain file types.

Here are some examples of what those files look like:

  • javascript.json: JavaScript files
  • typescript.json: TypeScript files
  • javascriptreact.json: JSX files
  • typescriptreact.json: TSX files
  • markdown.json: Markdown files
  • html.json: HTML files
  • css.json: CSS files

Global Snippets

For snippets that work across all file types:

  1. Choose "New Global Snippets file" when creating snippets
  2. Save with a descriptive name (e.g., general-snippets.code-snippets)

Snippets are a simple way to speed up your development workflow. By investing a little time in creating well-thought-out snippets, you can spend more time-solving problems and less time writing boilerplate.

Start with a few snippets for your most common patterns and gradually build your library as you identify more opportunities for automation in your workflow.

Vscode
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.