I needed a place to store code snippets, email templates, and frequently pasted text blocks. Everything I found was either a full IDE extension, a note-taking app in disguise, or yet another Electron app eating 200MB of RAM. So I built TypeFast — a snippet manager that runs in a browser tab.
The Snippet Graveyard Problem
Every developer has one. A folder called snippets or useful-stuff sitting somewhere in their home directory. A Notion page titled “Code Templates” that hasn’t been updated since 2023. Three GitHub Gists they can’t find because they never gave them proper names. Slack messages to themselves that got buried under 400 notifications.
The common thread: the tool was never designed for quick retrieval. Notion is a document editor. Gists are for sharing, not searching. Slack is for messaging. Using them as snippet managers is like using a spreadsheet as a to-do list — it technically works, but the friction kills you.
What TypeFast Actually Does
TypeFast has exactly four features:
- Add a snippet — give it a title, a category, paste the content
- Find a snippet — type in the search bar, or filter by category tab
- Copy a snippet — one click, it’s on your clipboard, a “✅ Copied!” confirmation appears
- Edit or delete — because snippets evolve
That’s it. No folders, no tags cloud, no sharing, no collaboration, no AI suggestions. Just a fast, searchable list with a copy button.
The Technical Non-Architecture
TypeFast is a single HTML file. No React, no Vue, no build step. The entire application — HTML, CSS, and JavaScript — weighs about 10KB. It stores data in localStorage, which means:
- No server, no database, no API calls
- Data persists across browser sessions
- No account, no sync, no privacy concerns
- Works offline (it’s also a PWA)
The trade-off is obvious: your snippets live only in that browser, on that device. If you clear your browser data, they’re gone. For most people, this is fine — snippets aren’t precious documents. But if you want durability, export them (coming in a future update) or just keep the tab pinned.
How the App Architecture Works
Most web apps start with npx create-react-app and immediately inherit thousands of dependencies, a build pipeline, and a node_modules folder heavier than the app itself. TypeFast takes the opposite approach: vanilla JavaScript with zero dependencies, organized around an event-driven pattern that would look familiar to anyone who wrote web apps before the framework era.
The DOM manipulation strategy is intentionally boring. Instead of a virtual DOM or reactive bindings, TypeFast uses document.createElement() for building snippet cards and direct property assignment for updates. When the snippet list changes, the app clears the container and rebuilds it. For a list of a few hundred items, this is imperceptibly fast — the browser’s layout engine handles it in under a frame.
State management is a plain JavaScript object that gets serialized to localStorage on every mutation. Here’s the actual core data model:
// Core data model — everything TypeFast needs
const AppState = {
snippets: [],
categories: ['General'],
activeCategory: 'All',
searchQuery: ''
};
// Persist to localStorage on every mutation
function saveState() {
localStorage.setItem('typefast_data', JSON.stringify({
snippets: AppState.snippets,
categories: AppState.categories
}));
}
// Hydrate on startup
function loadState() {
const saved = localStorage.getItem('typefast_data');
if (saved) {
const data = JSON.parse(saved);
AppState.snippets = data.snippets || [];
AppState.categories = data.categories || ['General'];
}
}
That’s the entire state layer. No Redux store with actions and reducers. No Vuex modules. No React context providers wrapping five levels deep. A single object, two functions, and localStorage as the persistence layer. When something changes, call saveState(). When the page loads, call loadState(). The simplicity is the feature — there are zero state synchronization bugs because there’s only one source of truth.
Code Walkthrough: The Snippet Engine
The search and filter system is the heart of TypeFast. Every keystroke in the search bar triggers a filter pass across all snippets. Here’s the actual implementation:
function filterSnippets() {
const query = AppState.searchQuery.toLowerCase();
const category = AppState.activeCategory;
return AppState.snippets.filter(snippet => {
const matchesCategory = category === 'All' || snippet.category === category;
const matchesSearch = !query ||
snippet.title.toLowerCase().includes(query) ||
snippet.content.toLowerCase().includes(query) ||
snippet.category.toLowerCase().includes(query);
return matchesCategory && matchesSearch;
});
}
It searches across title, content, and category simultaneously. No fancy indexing, no search library — just Array.filter() and String.includes(). For collections under a few thousand snippets, this brute-force approach is faster than the overhead of maintaining a search index.
The more interesting piece is the template variable system. TypeFast lets you embed dynamic placeholders in your snippets that get expanded at copy time. Type {{date}} in a snippet and it becomes today’s date when you copy it:
// Template variables — type {{date}} and get today's date
const TEMPLATE_VARS = {
'{{date}}': () => new Date().toISOString().split('T')[0],
'{{time}}': () => new Date().toLocaleTimeString(),
'{{timestamp}}': () => Date.now().toString(),
'{{uuid}}': () => crypto.randomUUID(),
'{{clipboard}}': async () => {
try {
return await navigator.clipboard.readText();
} catch {
return '{{clipboard}}'; // fallback if permission denied
}
}
};
async function expandTemplateVars(text) {
let result = text;
for (const [pattern, resolver] of Object.entries(TEMPLATE_VARS)) {
if (result.includes(pattern)) {
const value = await resolver();
result = result.replaceAll(pattern, value);
}
}
return result;
}
The {{clipboard}} variable is particularly useful: it reads the current clipboard content and injects it into the snippet. So you can create a template like git commit -m "{{clipboard}}", copy some text, then copy the snippet, and the clipboard content gets wrapped in the git command. The copy-to-clipboard function processes all template variables before writing to the clipboard, so the user always gets the fully expanded version.
The one-click copy includes visual feedback so you know something happened:
async function copySnippet(snippetId) {
const snippet = AppState.snippets.find(s => s.id === snippetId);
if (!snippet) return;
const expanded = await expandTemplateVars(snippet.content);
await navigator.clipboard.writeText(expanded);
// Visual feedback
const btn = document.querySelector(`[data-copy="${snippetId}"]`);
const original = btn.textContent;
btn.textContent = '✅ Copied!';
btn.classList.add('copied');
setTimeout(() => {
btn.textContent = original;
btn.classList.remove('copied');
}, 1500);
}
The 1500ms timeout for the feedback animation is deliberate — long enough to register visually, short enough that it resets before you need to copy another snippet. The copied CSS class triggers a brief green highlight animation on the button. Small detail, but it’s the difference between “did that work?” and “done, next.”
Performance: TypeFast vs Electron Alternatives
The entire reason TypeFast exists is that snippet managers shouldn’t need Electron. Here’s how it compares against typical alternatives:
| Metric | TypeFast | Electron Snippet Manager | VS Code Extension |
|---|---|---|---|
| RAM Usage | ~15MB (browser tab) | 180–250MB | ~50MB (VS Code overhead) |
| Disk Space | 12KB | 150–300MB | 2–5MB + VS Code |
| Startup Time | <100ms | 2–4 seconds | 1–2 seconds (cold) |
| Works Offline | ✔ (PWA) | ✔ | ✔ |
| Search Speed | Instant (<1ms for 1000 snippets) | ~50ms | ~100ms |
| Dependencies | Zero | Node.js, Chromium | VS Code |
I tested this by loading 1,000 snippets into TypeFast and measuring search latency with performance.now(). The filter function runs in under 1ms because it’s just Array.filter() on a JavaScript array that’s already in memory. No database queries, no IPC calls, no virtual DOM diffing. The bottleneck isn’t the search — it’s the DOM rebuild, which still finishes in under 16ms (one frame at 60fps).
RAM usage is the most dramatic difference. An Electron app bundles an entire Chromium instance, which starts at about 80MB before your app code even loads. TypeFast shares the Chromium instance you already have open — your browser. The marginal cost of one more tab is roughly 15MB, and that includes the full snippet dataset.
The Build and Deploy Pipeline (There Isn’t One)
TypeFast has no build step. No webpack config, no Vite setup, no Babel transpilation. The source code is the production artifact. This is a deliberate choice, not a limitation — when your entire app is a single HTML file, build tooling adds complexity without adding value.
The app is served by nginx running on my homelab TrueNAS box. Here’s the full server config:
server {
listen 443 ssl http2;
server_name typefast.orthogonal.info;
root /usr/share/nginx/typefast;
index index.html;
# Cache everything aggressively — it's one file
location / {
add_header Cache-Control "public, max-age=86400";
try_files $uri $uri/ /index.html;
}
# Security headers
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline'";
}
The entire deploy pipeline is one line:
scp index.html [email protected]:/mnt/data/nginx/typefast/
No CI/CD, no Docker build, no artifact registry. When your app is a single file, you don’t need infrastructure. The security headers in the nginx config are honestly overkill for a static HTML file, but old habits die hard when you spend your day job doing security engineering. The Content-Security-Policy header restricts the page to only loading resources from itself, which means even if someone injected a script tag via a snippet, it wouldn’t be able to phone home. Defense in depth, even for a 12KB app.
Use Cases I Didn’t Expect
- A support team member saves 15 canned responses, copies the right one in under 2 seconds
- A writer keeps character descriptions and plot points for quick reference
- A sysadmin stores SSH commands, config blocks, and one-liners
- A recruiter saves personalized outreach templates by role type
Try It
It comes pre-loaded with two example snippets. Delete them, add your own, and see if it sticks. If you’re still using a text file for snippets in a week, I’ll be surprised.
📚 Related Articles
Get Weekly Security & DevOps Insights
Join 500+ engineers getting actionable tutorials on Kubernetes security, homelab builds, and trading automation. No spam, unsubscribe anytime.
Subscribe Free →Delivered every Tuesday. Read by engineers at Google, AWS, and startups.
Frequently Asked Questions
What is TypeFast: Snippet Manager Without Electron Bloat about?
I needed a place to store code snippets, email templates, and frequently pasted text blocks. Everything I found was either a full IDE extension, a note-taking app in disguise, or yet another Electron
Who should read this article about TypeFast: Snippet Manager Without Electron Bloat?
Anyone interested in learning about TypeFast: Snippet Manager Without Electron Bloat and related topics will find this article useful.
What are the key takeaways from TypeFast: Snippet Manager Without Electron Bloat?
So I built TypeFast — a snippet manager that runs in a browser tab. The Snippet Graveyard Problem Every developer has one. A folder called snippets or useful-stuff sitting somewhere in their home dire
📧 Get weekly insights on security, trading, and tech. No spam, unsubscribe anytime.

Leave a Reply