πŸ“ Tutorials
Β· 3 min read

Build an AI-Powered Code Snippet Manager


You find a useful code pattern on Stack Overflow. You copy it somewhere β€” a text file, a Notion page, a GitHub Gist. Three weeks later, you need it again and can’t find it.

In this tutorial, we’ll build snip β€” a CLI tool that saves code snippets and uses AI to auto-tag, describe, and search them. Save a snippet in 5 seconds, find it in 2.

What we’re building

# Save a snippet (AI auto-generates tags and description)
$ snip save "Express error handler middleware"
# Opens your $EDITOR, paste the code, save and close

βœ… Saved: Express error handler middleware
   Tags: express, middleware, error-handling, nodejs
   Language: javascript

# Search by natural language
$ snip find "how to handle errors in express"

1. Express error handler middleware (javascript)
   Tags: express, middleware, error-handling, nodejs
   Saved: 2026-03-25

# View the snippet
$ snip show 1

The code

#!/usr/bin/env node
// index.js
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
import { homedir } from 'os';
import { join } from 'path';
import { execSync } from 'child_process';
import Anthropic from '@anthropic-ai/sdk';

const STORE = join(homedir(), '.snip');
const DB = join(STORE, 'snippets.json');
if (!existsSync(STORE)) mkdirSync(STORE);
if (!existsSync(DB)) writeFileSync(DB, '[]');

const snippets = JSON.parse(readFileSync(DB, 'utf-8'));
const save = () => writeFileSync(DB, JSON.stringify(snippets, null, 2));

const anthropic = new Anthropic();
const [,, command, ...args] = process.argv;

if (command === 'save') {
  const title = args.join(' ') || 'Untitled snippet';
  
  // Open editor for code input
  const tmpFile = join(STORE, 'tmp.txt');
  writeFileSync(tmpFile, '');
  execSync(`${process.env.EDITOR || 'nano'} ${tmpFile}`, { stdio: 'inherit' });
  const code = readFileSync(tmpFile, 'utf-8').trim();
  
  if (!code) { console.log('Empty snippet, not saved.'); process.exit(0); }

  // AI generates tags and description
  const response = await anthropic.messages.create({
    model: 'claude-haiku-3.5',
    max_tokens: 200,
    messages: [{
      role: 'user',
      content: `Analyze this code snippet titled "${title}":

\`\`\`
${code.slice(0, 2000)}
\`\`\`

Return JSON only:
{"language": "...", "tags": ["tag1", "tag2", ...], "description": "one sentence description"}

Use lowercase tags. Max 6 tags. Be specific (e.g., "react-hooks" not just "react").`
    }],
  });

  let meta;
  try {
    meta = JSON.parse(response.content[0].text);
  } catch {
    meta = { language: 'unknown', tags: [], description: title };
  }

  snippets.push({
    id: snippets.length + 1,
    title,
    code,
    ...meta,
    created: new Date().toISOString().split('T')[0],
  });
  save();
  
  console.log(`βœ… Saved: ${title}`);
  console.log(`   Tags: ${meta.tags.join(', ')}`);
  console.log(`   Language: ${meta.language}`);

} else if (command === 'find') {
  const query = args.join(' ').toLowerCase();
  const results = snippets.filter(s => 
    s.title.toLowerCase().includes(query) ||
    s.tags.some(t => t.includes(query)) ||
    s.description.toLowerCase().includes(query) ||
    s.language.includes(query)
  );

  if (!results.length) { console.log('No snippets found.'); process.exit(0); }
  
  results.forEach(s => {
    console.log(`${s.id}. ${s.title} (${s.language})`);
    console.log(`   Tags: ${s.tags.join(', ')}`);
    console.log(`   ${s.created}\n`);
  });

} else if (command === 'show') {
  const id = parseInt(args[0]);
  const snippet = snippets.find(s => s.id === id);
  if (!snippet) { console.log('Snippet not found.'); process.exit(1); }
  
  console.log(`# ${snippet.title}`);
  console.log(`# ${snippet.description}`);
  console.log(`# Tags: ${snippet.tags.join(', ')}\n`);
  console.log(snippet.code);

} else if (command === 'list') {
  snippets.forEach(s => console.log(`${s.id}. ${s.title} (${s.language}) β€” ${s.created}`));

} else {
  console.log('Usage: snip <save|find|show|list> [args]');
  console.log('  snip save "title"     Save a new snippet');
  console.log('  snip find "query"     Search snippets');
  console.log('  snip show <id>        Show a snippet');
  console.log('  snip list             List all snippets');
}

Setup

mkdir snip-cli && cd snip-cli
npm init -y && npm install @anthropic-ai/sdk
# Add "bin": {"snip": "./index.js"} to package.json
chmod +x index.js && npm link

Usage examples

# Save from clipboard (macOS)
pbpaste | snip save "Docker multi-stage build"

# Save interactively
snip save "PostgreSQL connection pool setup"
# Editor opens, paste code, save

# Find snippets
snip find "docker"
snip find "authentication"
snip find "python"

# List everything
snip list

Making it better

  • Semantic search: Use embeddings instead of keyword matching for smarter search
  • Sync: Store snippets in a GitHub Gist for cross-machine access
  • Import: Bulk import from GitHub Gists or a snippets folder
  • Export: Generate a searchable HTML page of all your snippets
  • Pipe support: cat file.js | snip save "my utility functions"

Total build time: ~30 minutes. API cost: ~$0.001 per snippet (Haiku).

Related: Best AI Coding Tools 2026 Β· VS Code Keyboard Shortcuts Β· Build a Git Diff Summarizer Β· Build Meeting Notes Summarizer

πŸ“˜