Every developer accumulates code snippets—Ansible playbooks, Terraform configs, shell scripts, quick Python utilities. Scattered across Gists, notes apps, and random text files, they’re never where you need them. Here’s how to build your own private snippet manager.

Architecture Overview

The solution is simple:

  • FastAPI backend with JSON file storage
  • Static HTML frontend with vanilla JavaScript
  • Prism.js for syntax highlighting
  • Hugo for deployment (optional, or serve directly)

The Data Model

1
2
3
4
5
6
7
8
9
class FileCreate(BaseModel):
    filename: str
    content: str
    language: str = ""

class FileUpdate(BaseModel):
    filename: Optional[str] = None
    content: Optional[str] = None
    language: Optional[str] = None

Files belong to projects. Each file stores:

  • filename - e.g., “deploy-webserver.yml”
  • content - the actual code
  • language - for syntax highlighting
  • Timestamps for sorting

Auto-Detecting Language

Rather than forcing users to select a language, detect it from the file extension:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def detect_language(filename: str, content: str) -> str:
    ext = filename.split('.')[-1].lower() if '.' in filename else ''
    
    lang_map = {
        'yml': 'yaml', 'yaml': 'yaml',
        'py': 'python', 
        'js': 'javascript', 'ts': 'typescript',
        'sh': 'bash', 'bash': 'bash',
        'json': 'json', 'sql': 'sql',
        'tf': 'terraform', 'hcl': 'terraform',
    }
    
    return lang_map.get(ext, 'text')

Frontend Syntax Highlighting

Prism.js makes this trivial. Include the CSS theme and language components:

1
2
3
4
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-yaml.min.js"></script>
<!-- Add more languages as needed -->

Then wrap your code:

1
2
3
<pre class="code-block">
  <code class="language-yaml">${escapeHtml(file.content)}</code>
</pre>

Call Prism.highlightAll() after rendering.

Dark Theme Styling

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
.file-content {
    background: #0d1117;
    border-radius: 8px;
    overflow: hidden;
}

.file-header {
    display: flex;
    justify-content: space-between;
    padding: 0.5rem 1rem;
    background: #161b22;
    border-bottom: 1px solid #30363d;
}

.code-block {
    padding: 1rem;
    overflow-x: auto;
    font-family: 'Monaco', 'Menlo', monospace;
    white-space: pre;
    color: #c9d1d9;
}

Why Not Use Gists?

GitHub Gists are great, but:

  • Public by default (secret gists are still discoverable)
  • No organization beyond descriptions
  • No project grouping
  • API rate limits if you build tooling around them

A private snippet manager gives you full control and works offline.

Authentication Considerations

For a personal tool, simple password authentication works:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PASSWORD_HASH = hashlib.sha256(password.encode()).hexdigest()

@app.post("/api/auth")
async def authenticate(req: AuthRequest):
    if hashlib.sha256(req.password.encode()).hexdigest() != PASSWORD_HASH:
        raise HTTPException(status_code=401)
    
    token = secrets.token_urlsafe(32)
    active_sessions[token] = {"created": datetime.now().isoformat()}
    return {"token": token}

For production, add token expiration and consider using proper secrets management.

Deployment

Run FastAPI behind a reverse proxy with HTTPS. Store the JSON data file in a persistent location (or upgrade to SQLite if you need querying).

The frontend can be served statically or through the same API. For ultimate simplicity, use a localtunnel or Cloudflare Tunnel for secure remote access.

Conclusion

A private code snippet manager is one of those tools that seems trivial until you have one. Suddenly your playbooks, configs, and scripts are organized, searchable, and syntax-highlighted—without touching a third-party service.

Total build time: about an hour. Value: saves countless “where did I put that script?” moments.