OrynthDev is a static, single-file HTML directory that showcases developer tools and projects from the Orynth community. It provides a clean, fast browsing experience with search, filtering, sorting, and upvoting — all without any backend infrastructure.
The goal is to make it easy for developers and users to discover quality tools, navigate by category, and surface community favorites through upvoting. Every tool listed links back to its listing on Orynth.dev, driving traffic to makers who have published there.
.html file. No npm, no build step, no server required. Open it in a browser and it works.
The site uses a deliberately minimal architecture — all logic, styles, and data live in a single self-contained HTML file.
orynthdev/
├── orynth-tools.html ← Main site (HTML + CSS + JS, self-contained)
├── README.md ← Setup and usage guide
└── docs/
└── project-docs.html ← This document
| Layer | Technology | Rationale |
|---|---|---|
| Markup | HTML5 | Semantic, accessible, no framework overhead |
| Styles | CSS3 (custom properties) | Themeable, no preprocessor needed |
| Logic | Vanilla JavaScript (ES6+) | No dependencies, fast parse time |
| Fonts | Google Fonts (Syne, DM Mono) | Distinctive typography, self-hostable |
| Data | Static JS array | Easy to edit; can swap for API fetch |
On page load, JavaScript reads the TOOLS array, applies any active filters, and renders cards into a CSS grid. Filter buttons, the search input, and the sort dropdown all call the same render() function, which re-derives the visible list from the current filter state.
Upvote state is stored in a Set and an object in memory — it resets on page reload. Persistent upvotes would require a backend or localStorage.
Each tool in the TOOLS array follows this schema:
{
id: Number, // Unique integer identifier
name: String, // Display name shown on card
icon: String, // Emoji or Unicode symbol for the card icon
category: String, // Category slug — must match a filter button data-cat
desc: String, // 1–2 sentence description shown on card
tags: String[], // Array of 2–3 short label strings
url: String, // External URL (opens in new tab on card click)
upvotes: Number, // Starting upvote count
newest: Number // Sort index for "Newest" mode (lower = newer)
}
{
id: 1,
name: "Vercel",
icon: "▲",
category: "infra",
desc: "Deploy web projects instantly. Push to git and get a live URL with edge functions, analytics, and previews built in.",
tags: ["Deploy", "Edge", "CI/CD"],
url: "https://vercel.com",
upvotes: 841,
newest: 1
}
| Slug | Label | Examples |
|---|---|---|
ai | AI / ML | Replicate, v0, Anthropic API, OpenAI |
devtools | Dev Tools | Cursor, Zed, Bun, Posthog |
api | APIs | Resend, Clerk, Liveblocks, Stripe |
ui | UI / Design | shadcn/ui, Framer Motion, Radix UI |
productivity | Productivity | Linear, Notion, Arc |
infra | Infra | Vercel, Supabase, Railway, Neon, Cloudflare |
To add a new category, add a new entry to the TOOLS array with the new slug and add a matching filter button in the HTML.
<button class="filter-btn" data-cat="newcat">New Category</button>
| Variable | Value | Usage |
|---|---|---|
--bg | #080808 | Page background |
--surface | #101010 | Input, search background |
--card | #141414 | Tool card background |
--card-hover | #1a1a1a | Card hover state |
--border | #222 | Default borders |
--accent | #c6f135 | Electric lime — CTAs, highlights |
--text | #f0efe8 | Primary text |
--text-muted | #666 | Secondary / descriptive text |
| Font | Role | Weights |
|---|---|---|
| Syne | Display — headings, logo, tool names | 400, 500, 600, 700, 800 |
| DM Mono | Mono — labels, descriptions, tags, inputs | 300, 400, 500 (+ italic) |
Cards fade up on render using CSS @keyframes fadeUp with staggered animation-delay (40ms per card). Hover states use 180ms transitions on background and opacity. The featured banner has a radial glow that pulses on hover.
No setup required. Open orynth-tools.html in any modern browser.
# Python 3 python -m http.server 8080 # Node.js npx serve . # Bun bun --bun run --hot . # Then open: # http://localhost:8080/orynth-tools.html
Open orynth-tools.html in any text editor. The three main areas to edit are:
| Area | Location in file |
|---|---|
| Tool data | const TOOLS = [...] in the <script> block |
| CSS variables / theme | :root { ... } near the top of <style> |
| Layout / categories | #filters div in the HTML body |
Edit the TOOLS array inside the <script> block. Each object must include all required fields from the data model. IDs should be unique integers; newest values should be unique and lower means "more recent".
// Add to end of TOOLS array:
{
id: 19,
name: "Your Tool",
icon: "🚀",
category: "devtools", // Use an existing slug
desc: "One or two sentences about what this tool does.",
tags: ["Tag1", "Tag2"],
url: "https://yourtool.com",
upvotes: 0,
newest: 19 // Lower = shows first in "Newest" sort
}
Find the .featured-banner div in the HTML body and update the name, description, tags, and the two href and onclick URL references.
When Orynth exposes a public API, replace the static array with a fetch() call. Example pattern:
async function loadTools() {
const res = await fetch('https://api.orynth.dev/projects');
const data = await res.json();
// Map API response to TOOLS schema
TOOLS.length = 0; // Clear static array
data.projects.forEach((p, i) => {
TOOLS.push({
id: p.id,
name: p.name,
icon: p.emoji || '◈',
category: p.category_slug,
desc: p.short_description,
tags: p.tags.slice(0, 3),
url: `https://orynth.dev/p/${p.slug}`,
upvotes: p.upvote_count,
newest: i
});
});
document.getElementById('total-count').textContent = TOOLS.length;
render();
}
loadTools();
render() call at the bottom of the script with loadTools() to use dynamic data.Because the entire site is a single static HTML file, it can be hosted anywhere with no build configuration.
| Platform | Steps | Cost |
|---|---|---|
| Vercel | Drag & drop the file in the Vercel dashboard | Free |
| Netlify | Drop into Netlify Drop, or connect a GitHub repo | Free |
| GitHub Pages | Push to repo root, enable Pages on main branch | Free |
| Cloudflare Pages | Connect repo, no build command, publish dir / | Free |
| Railway | Static site deploy via GitHub repo | Free tier |
All platforms above support custom domains. Point your domain's DNS to the platform, add the domain in the dashboard, and SSL is handled automatically.
Community contributions are welcome. To add a tool to the directory:
TOOLS array following the schema in Section 4desc to 1–2 sentences maximumTools should be actively maintained, publicly accessible, and genuinely useful to developers or makers. Avoid duplicates — check the existing list before submitting. Commercial tools are welcome; tools must not be malware, spam, or violate Orynth's policies.
| Priority | Feature | Notes |
|---|---|---|
| High | Orynth API integration | Replace static array with live data from orynth.dev |
| High | Persistent upvotes | Sync upvotes to Orynth API or localStorage fallback |
| Medium | Tool detail pages | Expanded view with screenshots, maker info, external links |
| Medium | Collections | Curated lists (e.g., "Best free tools", "AI stack 2026") |
| Medium | Maker profiles | Link tools to their Orynth maker page |
| Low | Dark / light toggle | User-preferred theme with localStorage persistence |
| Low | Submit modal | In-page form that deep-links to orynth.dev submission |
| Low | RSS / changelog | Weekly digest of new tools added to the directory |