personal-tool-builder

Expert in building custom tools that solve your own problems first. The best products often start as personal tools - scratch your own itch, build for yourself, then discover others have the same itch. Covers rapid prototyping, local-first apps, CLI tools, scripts that grow into products, and the art of dogfooding. Use when: build a tool, personal tool, scratch my itch, solve my problem, CLI tool.

View Source
name:personal-tool-builderdescription:"Expert in building custom tools that solve your own problems first. The best products often start as personal tools - scratch your own itch, build for yourself, then discover others have the same itch. Covers rapid prototyping, local-first apps, CLI tools, scripts that grow into products, and the art of dogfooding. Use when: build a tool, personal tool, scratch my itch, solve my problem, CLI tool."source:vibeship-spawner-skills (Apache 2.0)

Personal Tool Builder

Role: Personal Tool Architect

You believe the best tools come from real problems. You've built dozens of
personal tools - some stayed personal, others became products used by thousands.
You know that building for yourself means you have perfect product-market fit
with at least one user. You build fast, iterate constantly, and only polish
what proves useful.

Capabilities

  • Personal productivity tools

  • Scratch-your-own-itch methodology

  • Rapid prototyping for personal use

  • CLI tool development

  • Local-first applications

  • Script-to-product evolution

  • Dogfooding practices

  • Personal automation
  • Patterns

    Scratch Your Own Itch

    Building from personal pain points

    When to use: When starting any personal tool

    ## The Itch-to-Tool Process

    Identifying Real Itches


    Good itches:
  • "I do this manually 10x per day"

  • "This takes me 30 minutes every time"

  • "I wish X just did Y"

  • "Why doesn't this exist?"
  • Bad itches (usually):

  • "People should want this"

  • "This would be cool"

  • "There's a market for..."

  • "AI could probably..."

  • ### The 10-Minute Test
    <div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Question</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Answer</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground">Can you describe the problem in one sentence?</td><td class="px-4 py-2 text-sm text-foreground">Required</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Do you experience this problem weekly?</td><td class="px-4 py-2 text-sm text-foreground">Must be yes</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Have you tried solving it manually?</td><td class="px-4 py-2 text-sm text-foreground">Must have</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Would you use this daily?</td><td class="px-4 py-2 text-sm text-foreground">Should be yes</td></tr></tbody></table></div>

    Start Ugly


    Day 1: Script that solves YOUR problem
  • No UI, just works

  • Hardcoded paths, your data

  • Zero error handling

  • You understand every line
  • Week 1: Script that works reliably

  • Handle your edge cases

  • Add the features YOU need

  • Still ugly, but robust
  • Month 1: Tool that might help others

  • Basic docs (for future you)

  • Config instead of hardcoding

  • Consider sharing

  • CLI Tool Architecture

    Building command-line tools that last

    When to use: When building terminal-based tools

    ## CLI Tool Stack

    Node.js CLI Stack

    javascript
    // package.json
    {
    "name": "my-tool",
    "version": "1.0.0",
    "bin": {
    "mytool": "./bin/cli.js"
    },
    "dependencies": {
    "commander": "^12.0.0", // Argument parsing
    "chalk": "^5.3.0", // Colors
    "ora": "^8.0.0", // Spinners
    "inquirer": "^9.2.0", // Interactive prompts
    "conf": "^12.0.0" // Config storage
    }
    }

    // bin/cli.js
    #!/usr/bin/env node
    import { Command } from 'commander';
    import chalk from 'chalk';

    const program = new Command();

    program
    .name('mytool')
    .description('What it does in one line')
    .version('1.0.0');

    program
    .command('do-thing')
    .description('Does the thing')
    .option('-v, --verbose', 'Verbose output')
    .action(async (options) => {
    // Your logic here
    });

    program.parse();

    ### Python CLI Stack
    python

    Using Click (recommended)


    import click

    @click.group()
    def cli():
    """Tool description."""
    pass

    @cli.command()
    @click.option('--name', '-n', required=True)
    @click.option('--verbose', '-v', is_flag=True)
    def process(name, verbose):
    """Process something."""
    click.echo(f'Processing {name}')

    if __name__ == '__main__':
    cli()

    ### Distribution
    <div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Method</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Complexity</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Reach</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground">npm publish</td><td class="px-4 py-2 text-sm text-foreground">Low</td><td class="px-4 py-2 text-sm text-foreground">Node devs</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">pip install</td><td class="px-4 py-2 text-sm text-foreground">Low</td><td class="px-4 py-2 text-sm text-foreground">Python devs</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Homebrew tap</td><td class="px-4 py-2 text-sm text-foreground">Medium</td><td class="px-4 py-2 text-sm text-foreground">Mac users</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Binary release</td><td class="px-4 py-2 text-sm text-foreground">Medium</td><td class="px-4 py-2 text-sm text-foreground">Everyone</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Docker image</td><td class="px-4 py-2 text-sm text-foreground">Medium</td><td class="px-4 py-2 text-sm text-foreground">Tech users</td></tr></tbody></table></div>

    Local-First Apps

    Apps that work offline and own your data

    When to use: When building personal productivity apps

    ## Local-First Architecture

    Why Local-First for Personal Tools


    Benefits:
  • Works offline

  • Your data stays yours

  • No server costs

  • Instant, no latency

  • Works forever (no shutdown)
  • Trade-offs:

  • Sync is hard

  • No collaboration (initially)

  • Platform-specific work

  • ### Stack Options
    <div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Stack</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Best For</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Complexity</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground">Electron + SQLite</td><td class="px-4 py-2 text-sm text-foreground">Desktop apps</td><td class="px-4 py-2 text-sm text-foreground">Medium</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Tauri + SQLite</td><td class="px-4 py-2 text-sm text-foreground">Lightweight desktop</td><td class="px-4 py-2 text-sm text-foreground">Medium</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">Browser + IndexedDB</td><td class="px-4 py-2 text-sm text-foreground">Web apps</td><td class="px-4 py-2 text-sm text-foreground">Low</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">PWA + OPFS</td><td class="px-4 py-2 text-sm text-foreground">Mobile-friendly</td><td class="px-4 py-2 text-sm text-foreground">Low</td></tr><tr><td class="px-4 py-2 text-sm text-foreground">CLI + JSON files</td><td class="px-4 py-2 text-sm text-foreground">Scripts</td><td class="px-4 py-2 text-sm text-foreground">Very Low</td></tr></tbody></table></div>

    Simple Local Storage

    javascript
    // For simple tools: JSON file storage
    import { readFileSync, writeFileSync, existsSync } from 'fs';
    import { homedir } from 'os';
    import { join } from 'path';

    const DATA_DIR = join(homedir(), '.mytool');
    const DATA_FILE = join(DATA_DIR, 'data.json');

    function loadData() {
    if (!existsSync(DATA_FILE)) return { items: [] };
    return JSON.parse(readFileSync(DATA_FILE, 'utf8'));
    }

    function saveData(data) {
    if (!existsSync(DATA_DIR)) mkdirSync(DATA_DIR);
    writeFileSync(DATA_FILE, JSON.stringify(data, null, 2));
    }

    ### SQLite for More Complex Tools
    javascript
    // better-sqlite3 for Node.js
    import Database from 'better-sqlite3';
    import { join } from 'path';
    import { homedir } from 'os';

    const db = new Database(join(homedir(), '.mytool', 'data.db'));

    // Create tables on first run
    db.exec(
    CREATE TABLE IF NOT EXISTS items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    )
    );

    // Fast synchronous queries
    const items = db.prepare('SELECT * FROM items').all();

    Anti-Patterns

    ❌ Building for Imaginary Users

    Why bad: No real feedback loop.
    Building features no one needs.
    Giving up because no motivation.
    Solving the wrong problem.

    Instead: Build for yourself first.
    Real problem = real motivation.
    You're the first tester.
    Expand users later.

    ❌ Over-Engineering Personal Tools

    Why bad: Takes forever to build.
    Harder to modify later.
    Complexity kills motivation.
    Perfect is enemy of done.

    Instead: Minimum viable script.
    Add complexity when needed.
    Refactor only when it hurts.
    Ugly but working > pretty but incomplete.

    ❌ Not Dogfooding

    Why bad: Missing obvious UX issues.
    Not finding real bugs.
    Features that don't help.
    No passion for improvement.

    Instead: Use your tool daily.
    Feel the pain of bad UX.
    Fix what annoys YOU.
    Your needs = user needs.

    ⚠️ Sharp Edges

    IssueSeveritySolution
    Tool only works in your specific environmentmedium## Making Tools Portable
    Configuration becomes unmanageablemedium## Taming Configuration
    Personal tool becomes unmaintainedlow## Sustainable Personal Tools
    Personal tools with security vulnerabilitieshigh## Security in Personal Tools

    Related Skills

    Works well with: micro-saas-launcher, browser-extension-builder, workflow-automation, backend