A real browser-based type foundry. TypeCraft loads any font as editable Bézier outlines, restyles the whole family with true geometric transforms, lets you redraw individual glyphs node-by-node, and compiles a production OpenType font entirely in the browser — no server, no installs.
Everything you see is the actual font: every preview is rendered with a real, freshly-compiled FontFace, not a CSS approximation.
▶ Try it now — live demo: https://sbrophy-dev.github.io/TypeCraft/
No account, no install. Projects live in your browser's localStorage; nothing leaves your machine.
- Start from real outlines. Remix one of ~19 curated open-licensed designs (Inter, Playfair, Space Mono, Bebas Neue, Caveat…) fetched as static WOFFs from the Fontsource CDN, upload your own TTF/OTF/WOFF, or open a blank canvas. Imported fonts are normalized to a 1000-UPM, Y-up outline model with consistent winding.
- Style with geometry, not tricks. Each control performs a genuine operation on the vectors:
- Weight offsets the outline along its normals (miter-limited, with self-intersection cleanup so heavy weights stay clean).
- Contrast thins horizontal strokes relative to vertical stems.
- Width / x-Height / Slant rescale, remap and shear the outlines.
- Rounding replaces sharp corners with Bézier fillets; Roughen adds deterministic hand-drawn jitter; Hollow turns letters into outlined forms.
- Redraw any glyph. A full vector workstation: pen, rectangle and ellipse tools; smart snapping to points, metric guides and a unit grid; per-glyph undo/redo; flip / rotate / align operations; a contour clipboard that works across glyphs (turn a
dinto ab); numeric coordinates; and a trace-reference underlay for drawing over any other glyph or the bundled template — all over live metric guides with a ghost of the original and the styled result. - Export a real font. Compile to OpenType in-browser and download OTF + WOFF2 + a CSS
@font-facekit + sample HTML, zipped.
- Framework: Next.js 15.3 (App Router)
- UI: React 19 + TypeScript 5.8
- Icons: Lucide React
- Font I/O: opentype.js (parse + assemble), woff2-encoder (WOFF2 compression)
- Packaging: JSZip
The geometry, transform pipeline and compiler are all bespoke and live in src/lib/typecraft/.
npm install
npm run dev| Command | Description |
|---|---|
npm run dev |
Start the dev server on port 3000 |
npm run build |
Production build |
npm run start |
Start the production server |
npm run lint |
Run ESLint |
npm run typecheck |
Run tsc --noEmit |
Tip: don't run
npm run buildwhilenpm run devis live — they share the.nextdirectory.
The app has no server dependencies (projects live in localStorage, fonts compile client-side, presets come from a CORS-enabled CDN), so it exports as a fully static site:
STATIC_EXPORT=1 npm run build # writes ./outEvery push to main builds and deploys the demo to GitHub Pages via .github/workflows/deploy-pages.yml. NEXT_PUBLIC_BASE_PATH handles the /TypeCraft subdirectory automatically.
src/
├── app/
│ ├── page.tsx # Marketing home + live hero demo
│ ├── dashboard/ # Project library + new-project flow
│ ├── editor/ # The editor (?project=<id>)
│ ├── preview/ # Read-only share view (?share=<id>)
│ └── billing/ # Pricing page
├── components/
│ ├── editor/
│ │ ├── TypeCraftEditor.tsx # Editor shell: state, history, compile, views
│ │ ├── StylePanel.tsx # Grouped style sliders + presets + bake
│ │ ├── PreviewViews.tsx # Type tester · waterfall · glyph grid
│ │ ├── GlyphEditor.tsx # The vector glyph editor
│ │ ├── ExportPanel.tsx # Metadata, formats, export
│ │ └── SharedPreview.tsx # Share view
│ ├── dashboard/NewProjectDialog.tsx
│ └── home/HomeHeroPreview.tsx # Live transform demo on the bundled Inter
└── lib/typecraft/
├── geometry.ts # Outline model: contours, offsetting, fillets,
│ # self-intersection cleanup, hit-testing
├── transforms.ts # The StyleParams pipeline (applyStyle)
├── font-model.ts # Parse a font binary → editable outlines
├── compile.ts # Project → opentype.js Font + live FontFace
├── accents.ts # Auto-composed accented Latin (é ñ ü ç …)
├── use-compiled-font.ts # React hook: debounced compile → CSS family
├── exporter.ts # OTF / WOFF2 / CSS kit / sample HTML → ZIP
├── charset.ts # Character coverage + glyph names
├── font-presets.ts # Curated open-licensed base designs
├── project.ts / storage.ts # Schema-3 project model + localStorage
└── types.ts
A project stores the imported base outlines (glyphs), any manual per-glyph overrides (edits), the global style parameters, and metrics. The "effective" outline for a glyph is its edit if present, otherwise the base; the style pipeline is applied on top at compile time. Bake folds the current style permanently into the outlines and resets the sliders, so you can layer further edits.
- Chromium 90+, Firefox 90+, Safari 14+
- Requires the
FontFaceAPI and WebAssembly (for WOFF2 compression)
MIT — see LICENSE. Exported fonts belong to you; respect the license of whatever base design you import (the bundled presets are all OFL or Apache).