π€ NoBadFonts is a next-generation, curated font discovery platform built for designers who demand quality, context, and performance β across web, Android, and iOS.
π Visit the Site Β· π¦ Try the CLI Β· π Report a Bug
- π― What Is This?
- β¨ Features
- πΈ Screenshots
- πΊοΈ App Structure Diagram
- ποΈ Architecture Overview
- βοΈ Tech Stack
- π¨ Color Palette
- πΎ Database Schema
- π Project Structure
- π Getting Started
- π± Mobile (Capacitor)
- π CLI Companion
- β FAQ
- π£οΈ Roadmap
- π₯οΈ Self-Hosting
- π€ Contributing
- π License
The internet has a font problem. Too many fonts. Too little curation. Zero context.
You open Google Fonts, see 1,400+ options, type "Hello World" in a tiny box, and somehow have to make a decision that'll define your entire brand. That's broken.
NoBadFonts fixes this. It's a curated typography platform at nobadfonts.in where:
- π¨ Fonts are previewed the way they'll actually be used β in dashboards, editorial layouts, and code editors
- π€ Every font has a real, generated description β not "beautiful, modern, versatile" filler copy
- β‘ Uploads are optimized in your browser via WebAssembly WOFF2 conversion before hitting the server
- π± The full experience works natively on Android and iOS via Capacitor
- π₯οΈ Developers can install fonts directly from the terminal with the companion CLI
This isn't a font gallery. It's a complete typography toolchain for people who take type seriously.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Preview Mode: [ UI / Dashboard ] [ Editorial ] [ Code ] β
β β
β βββββββββββββββ Typography in context, β
β β Dashboard β not in a vacuum. β
β β Widget β β
β βββββββββββββββ No more guessing if Inter looks β
β good in a tooltip. Just... see it. β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The FontTester.tsx component lets you preview fonts in three real-world contexts:
| Mode | Description |
|---|---|
| π₯οΈ UI / Dashboard | Buttons, tooltips, tables β the full product-design context |
| π° Editorial | Dense, multi-column text for readability testing |
| π» Code | Monospace fonts in a syntax-highlighted block |
The upload pipeline (src/pages/Upload.tsx) is where things get serious. Before a font even leaves your browser:
User uploads .ttf / .otf
β
βΌ
ββββββββββββββββ
β Validation β β Checks metadata, file type, required fields
ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββ
β Fingerprint β β Generates unique slug (e.g. "helvetica-now-display")
ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββββββββββ
β WASM WOFF2 Encoder β β Runs wawoff2 (Google's woff2 port) IN THE BROWSER
ββββββββ¬ββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Upload Compressed WOFF2 to Supabase β β Smaller. Faster. Better.
ββββββββββββββββββββββββββββββββββββββββ
β Users upload raw fonts. Servers receive optimized WOFF2. The network and your end-users thank you.
No more "A beautiful, modern, versatile typeface" placeholder copy. The engine at src/utils/fontDescriptionGenerator.ts analyzes a font's actual tag set and synthesizes something real:
// Input
tags: ['sans', 'geometric', 'modern', 'bold']
// Output
"A geometric sans-serif with a modern character.
Its bold weight makes it ideal for headlines and branding."Each description is unique to the font's personality. Curated at scale.
Stop guessing which fonts go together. The pairing interface (src/pages/FontPairing.tsx) lets you:
- Browse curated pairing recommendations
- Customize heading + body combinations in a live preview
- Filter by mood, category, and contrast style
See every character a font supports β before you commit. The GlyphMap.tsx component renders the full Unicode coverage of any typeface, so you know if it handles your language, symbols, or edge cases.
Uploaders get a private AnalyticsDashboard.tsx showing:
- Total views and downloads per font
- Geographic breakdown of interest
- Trending performance over time
| Feature | Description | Status |
|---|---|---|
| π¬ Context-Aware Type Tester | Preview fonts in UI, Editorial & Code contexts | β Live |
| β‘ Browser WOFF2 Conversion | WASM-powered TTF β WOFF2 before upload | β Live |
| π§ Algorithmic Description Engine | Auto-generates font copy from metadata tags | β Live |
| π Font Pairing Engine | Smart heading + body pairing suggestions | β Live |
| πΊοΈ Glyph Map Viewer | Full Unicode coverage display | β Live |
| π Analytics Dashboard | Views, downloads & geo stats per font | β Live |
| π± iOS & Android (Capacitor) | Native mobile with shared codebase | β Live |
| π₯οΈ CLI Tool | npx nobadfonts-cli add <font> |
β Live |
π Edge-generated fonts.css |
Remote embedding via Supabase Edge Functions | π§ Planned |
| π€ AI Font Recommendations | Personalized discovery via ML | π§ Planned |
| ποΈ Variable Font Axis Controls | Live weight/width sliders in the type tester | π§ Planned |
| π Dark Mode | System-aware theme toggle | π§ Planned |
| Role | Powers |
|---|---|
π€ member |
Upload fonts, manage their own library |
π‘οΈ admin |
Global curation rights, publish/unpublish any font, run FixWoff2Scanner |
Enforced at the database level via Supabase Row Level Security (RLS) β not just in the UI.
π Live at nobadfonts.in β visit to see it in action.
π Landing Page
π€ Font Catalog
π€ Font Details
π¬ Font Pairing
π¬ NoBadFonts-cli
π± Mobile View (Capacitor)
π€ Font Catalog| π€ Font Details
π¬ Font Pairing
π¬ NoBadFonts-cli
A high-level map of every page and how they connect:
graph TD
Home["π Home (Landing)"] --> Catalog["π Fonts Catalog"]
Home --> Auth["π Auth (Login/Signup)"]
Home --> Members["π₯ Members Directory"]
Home --> CLI["π₯οΈ CLI Docs Page"]
Catalog --> FontDetails["π€ Font Details"]
FontDetails --> TypeTester["π¬ Type Tester"]
FontDetails --> GlyphMap["πΊοΈ Glyph Map"]
FontDetails --> Pairing["π Font Pairing"]
Auth --> Profile["π€ Profile"]
Auth --> Upload["β¬οΈ Upload Pipeline"]
Auth --> AdminDash["π‘οΈ Admin Dashboard"]
Profile --> Analytics["π Analytics Dashboard"]
Profile --> FontGrid["πΌοΈ Font Grid (My Uploads)"]
Members --> MemberDetails["π§ Member Detail Page"]
MemberDetails --> DesignerFonts["π¨ Designer's Fonts"]
Upload --> WASM["β‘ WASM WOFF2 Encoder"]
WASM --> Supabase["βοΈ Supabase Storage"]
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NoBadFonts Platform β
β β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ β
β β Web App β β Android App β β iOS App β β
β β (Vite + β β (Capacitor) β β (Capacitor) β β
β β React 19) β β β β β β
β ββββββββ¬βββββββ ββββββββ¬ββββββββ ββββββββββββ¬ββββββββββββ β
β β β β β
β ββββββββββββββββββββΌβββββββββββββββββββββββββ β
β β Shared React Codebase (99%) β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β React 19 + TypeScript β β
β β β β
β β AuthContext βββΊ Supabase Auth β β
β β UploadContext βββΊ WASM WOFF2 Queue β β
β β Lenis + GSAP βββΊ Scroll Animations β β
β β Framer Motion βββΊ Micro-interactions β β
β βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Supabase Backend β β
β β β β
β β PostgreSQL βββΊ fonts, profiles, font_variants β β
β β Storage βββΊ Font files (.woff2, .ttf, .otf) β β
β β RLS Policies βββΊ Row-level auth enforcement β β
β β Edge Functions βββΊ (Future) fonts.css generation β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Technology | Version | Role |
|---|---|---|
| React | 19 RC | Core UI framework |
| TypeScript | 5.x | Type safety across the entire codebase |
| Vite | Latest | Build tool β instant HMR, optimized bundles |
| Tailwind CSS | v4 (Alpha) | Styling β new engine, sub-ms compile times |
| Framer Motion | Latest | Layout animations, modal transitions |
| GSAP + Lenis | Latest | Smooth scroll parallax effects |
| Technology | Role |
|---|---|
| Supabase | PostgreSQL + Auth + Storage + RLS |
| Vercel | Web deployment + edge CDN |
| Capacitor | iOS & Android native bridge |
| Technology | What It Does |
|---|---|
wawoff2 (WASM) |
Converts TTF β WOFF2 in the browser before upload |
| Algorithmic Desc. Engine | Synthesizes font descriptions from metadata tags |
| Supabase RLS | Database-level auth, not just UI-level |
The NoBadFonts design system is built around a high-contrast, type-forward aesthetic:
CREATE TABLE profiles (
id UUID PRIMARY KEY REFERENCES auth.users,
username TEXT UNIQUE NOT NULL,
role TEXT DEFAULT 'member' CHECK (role IN ('member', 'admin')),
avatar_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);CREATE TABLE fonts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
slug TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
user_id UUID REFERENCES profiles(id),
tags TEXT[],
category TEXT,
designer TEXT,
is_published BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);CREATE TABLE font_variants (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
font_id UUID REFERENCES fonts(id) ON DELETE CASCADE,
variant_name TEXT NOT NULL, -- e.g. "Bold Italic"
woff2_url TEXT, -- CDN link to compressed file
ttf_url TEXT,
file_size_woff2 BIGINT, -- For analytics
created_at TIMESTAMPTZ DEFAULT NOW()
);fonts table:
β
Anyone can SELECT published fonts
β
Authenticated users can INSERT their own fonts
β
Users can UPDATE/DELETE only their own rows
β
Admins have unrestricted access
nobadfonts/
β
βββ π .github/workflows/ # CI/CD pipelines
βββ π android/ # Capacitor Android project
βββ π logo/ # Brand assets
β
βββ π nobadfonts-cli/ # β Standalone CLI package
β βββ README.md
β
βββ π public/ # Static assets
βββ π scripts/ # Utility scripts
βββ π supabase/ # DB migrations & edge functions
β
βββ π src/
β
βββ π components/
β βββ π admin/
β β βββ FixWoff2Scanner.tsx # Admin tool: scan & fix broken woff2 refs
β β
β βββ π font-pairing/
β β βββ CustomizeSidebar.tsx # Live font pair customizer
β β βββ FontPickerSidebar.tsx # Browse & pick fonts for pairing
β β
β βββ π fonts/
β β βββ ContextPreview.tsx # UI / Editorial / Code preview modes
β β βββ Filters.tsx # Tag + category filtering
β β βββ FontCard.tsx # Card component in catalog grid
β β βββ FontTester.tsx # Interactive type tester
β β βββ GlyphMap.tsx # Full Unicode glyph coverage viewer
β β βββ LicenseInfo.tsx # License display
β β βββ PreviewAccordion.tsx # Expandable preview panel
β β βββ ShareModal.tsx # Share font link modal
β β βββ SocialShareCard.tsx # OG card generator
β β
β βββ π home/
β β βββ π Hero/ # Hero section variants (1, 2, 4)
β β βββ Land2.tsx ... Land8.tsx # Landing page sections
β β βββ Landing.tsx
β β
β βββ π layout/
β β βββ Footer.tsx
β β βββ Layout.tsx
β β βββ Navbar.tsx
β β βββ ScrollRestoration.tsx
β β
β βββ π profile/
β β βββ AnalyticsDashboard.tsx # Font performance stats
β β βββ FontGrid.tsx # Profile's uploaded fonts
β β βββ ProfileHeader.tsx
β β βββ SettingsForm.tsx
β β
β βββ π shared/
β β βββ EmptyState.tsx
β β βββ ErrorBoundary.tsx
β β βββ SEO.tsx
β β
β βββ UploadProgressPopup.tsx # Background upload progress indicator
β
βββ π contexts/
β βββ AuthContext.tsx # Supabase auth state: user, session, profile
β βββ UploadContext.tsx # WOFF2 conversion queue management
β
βββ π hooks/
β βββ useFont.ts # Single font data fetching
β βββ useFonts.ts # Catalog data fetching with filters
β βββ useLenis.ts # Smooth scroll β GSAP ScrollTrigger bridge
β βββ useMediaQuery.ts # Responsive breakpoint detection
β βββ useViewMode.ts # Grid vs list view toggle
β
βββ π pages/
β βββ AdminDashboard.tsx # Admin-only moderation panel
β βββ Auth.tsx # Login / signup
β βββ Cli.tsx # CLI documentation page
β βββ DesignerFonts.tsx # Fonts filtered by designer
β βββ FontDetails.tsx # Full font detail page
β βββ FontPairing.tsx # Pair fonts interactively
β βββ FontsCatalog.tsx # Main browsable catalog
β βββ Home.tsx # Landing page
β βββ MemberDetails.tsx # Public profile view
β βββ Members.tsx # Community directory
β βββ Profile.tsx # Private user profile
β βββ Upload.tsx # Multi-stage upload pipeline
β
βββ π types/
β βββ database.types.ts # Supabase-generated DB types
β βββ font.ts # FontVariant, FontData interfaces
β
βββ π utils/
β βββ fontDescriptionGenerator.ts # Algorithmic description synthesis
β βββ woff2.ts # WASM WOFF2 encoder wrapper
β
βββ App.tsx
βββ fonts.css # @font-face declarations
βββ index.css
βββ main.tsx
NoBadFonts is a live product at nobadfonts.in. No setup needed β just open it in your browser.
| What you want to do | Where to go |
|---|---|
| π€ Browse & preview fonts | nobadfonts.in/fonts |
| π Pair fonts together | nobadfonts.in/pairing |
| β¬οΈ Upload your typeface | Create a free account, then hit Upload |
| π₯οΈ Use fonts in your project via CLI | See CLI Companion below |
| π± Use on mobile | Download the Android / iOS app |
The source code is open β if you want to run your own instance, here's how.
Node.js β₯ 20.x
npm β₯ 10.x (or pnpm)
# Install dependencies
npm install
# Configure environment
cp .env.example .envAdd your Supabase credentials to .env:
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your_supabase_anon_keyπ‘ Get these from your Supabase Dashboard β Project Settings β API
# Start dev server
npm run dev
# β http://localhost:5173
# Build for production
npm run buildNoBadFonts runs natively on Android and iOS using Capacitor. 99% of the codebase is shared.
# Sync the web build into the native project
npx cap sync
# Open in Android Studio
npx cap open androidnpx cap sync
npx cap open ios # Requires macOS + Xcode| Plugin | Purpose |
|---|---|
@capacitor/filesystem |
Read/write font files locally |
@capacitor/haptics |
Tactile feedback on interactions |
For developers who prefer living in the terminal, NoBadFonts ships with a companion CLI.
# Install globally
npm install -g nobadfonts-cli
# Add a font to your project
npx nobadfonts-cli add inter
# List all available curated fonts
npx nobadfonts-cli list
# Search by category
npx nobadfonts-cli search --category="geometric-sans"The CLI automatically downloads the WOFF2 file, injects the @font-face declaration into your fonts.css, and keeps everything organized.
π Full docs:
nobadfonts-cli/README.md
Q: Is NoBadFonts free to use?
Yes β browsing, previewing, and discovering fonts is completely free. Creating an account to upload your own typefaces is also free.
Q: What font formats can I upload?
.ttf,.otf,.woff, and.woff2are all accepted. If you upload a.ttfor.otf, NoBadFonts automatically converts it to.woff2in your browser before uploading β so your fonts load faster for everyone.
Q: Can I use the fonts I find here in commercial projects?
License information is shown on every font's detail page. Always check the specific font's license before using it in commercial work.
Q: How does the CLI work?
Install it with
npm install -g nobadfonts-cli, then runnpx nobadfonts-cli add <fontname>. It fetches the WOFF2, writes the@font-facerule into your CSS, and you're done in one command.
Q: Is there a mobile app?
Yes β NoBadFonts is available as a native Android and iOS app with the same full feature set as the website.
Q: I found a bug or have a feature idea. Where do I go?
Open an issue on GitHub Issues β all feedback is read and considered.
- Context-aware type tester (UI / Editorial / Code modes)
- Browser-side WOFF2 conversion with WASM
- Algorithmic font description generator
- Font pairing engine
- Glyph map viewer
- Capacitor mobile (Android + iOS)
- CLI companion tool
- Admin dashboard with curation tools
- Supabase Edge Function β generate
fonts.cssfor remote embedding - AI-powered font recommendation engine
- Variable font axis controls in the type tester
- Dark mode
- Font collections / bookmarks
Thanks to everyone who has contributed to NoBadFonts!
Want to see your avatar here? Check out the Contributing section and open a PR!
Distributed under the MIT License. See LICENSE for full text.
Built with π€ by Bismay
nobadfonts.in β Stop using bad fonts.
ββββ βββ βββββββ βββββββ ββββββ βββββββ ββββββββ βββββββ ββββ ββββββββββββββββββββ
βββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββ
ββββββ ββββββ ββββββββββββββββββββββ βββββββββ βββ βββββββββ βββ βββ ββββββββ
βββββββββββββ ββββββββββββββββββββββ βββββββββ βββ βββββββββββββ βββ ββββββββ
βββ ββββββββββββββββββββββββββ ββββββββββββββ ββββββββββββ ββββββ βββ ββββββββ
βββ βββββ βββββββ βββββββ βββ ββββββββββ βββ βββββββ βββ βββββ βββ ββββββββ









