npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@k8ordo/framework

v1.4.2

Published

The k8ordo framework: routes/ compiled into React Server Components, run with or without a server.

Readme

@k8ordo/framework

Turns src/routes/ into an application of React Server Components, built with Vite, and lets the same routes run with or without a server. mode: 'static' renders every page at build time into files any static host serves. mode: 'server' renders per request, which is what gives an application Server Actions, guards, cookies and a real 404. The routes, the boundaries and the request handler are the same in both.

Like every k8ordo package it assumes React 19 and Server Components, uses only what has reached Baseline newly available, and ships no polyfills or legacy fallbacks.

  • Documentation: https://ordo.k8o.me/en/framework
  • Design guide: docs/GUIDE.md — shipped inside this package

Installation

npm install react react-dom server-only
npm install -D @k8ordo/framework @k8ordo/router vite typescript @types/node @types/react @types/react-dom
# or
pnpm add react react-dom server-only
pnpm add -D @k8ordo/framework @k8ordo/router vite typescript @types/node @types/react @types/react-dom

@k8ordo/router is a required peer, so the application and the framework share one copy, but the application imports from @k8ordo/framework, which re-exports what it needs (href, notFound, PageProps, …). Both are dev dependencies in either mode: the build bundles what the application runs.

Peer Dependencies

| Package | Version | Required | Needed for | | --------------------- | -------- | -------- | ------------------------------------------ | | @k8ordo/router | ^1.4.2 | yes | routing, re-exported by the framework | | react | ≥19.3.0 | yes | rendering | | react-dom | ≥19.3.0 | yes | rendering | | vite | ≥8.1.0 | yes | the build (framework() is a Vite plugin) | | oxc-transform-react | ^0.152.0 | optional | reactCompiler: true (React Compiler) |

Quick Start

// vite.config.ts
import { framework } from '@k8ordo/framework/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    framework({
      mode: 'static',
      paths: () => ['/products/1', '/products/2'], // for routes with parameters
      site: 'https://example.com', // and a sitemap.xml
    }),
  ],
});
// or: framework({ mode: 'server' }) — rendered per request
src/routes/
  layout.tsx            <html> and <body>; wraps everything through `children`
  page.tsx              /
  not-found.tsx         static: 404.html — server: a real 404
  error.tsx             shown in place of what is below when it throws
  products/[id]/
    page.tsx            /products/:id — `export const paramsSchema` types :id
    fallback.tsx        static: the shell for the ids paths does not list
  old/redirect.ts       /old sends the visitor elsewhere
  feed.xml/route.ts     /feed.xml answered by its GET — a Response, not a page
  admin/guard.ts        server mode: runs before everything under /admin
// src/routes/products/[id]/page.tsx
import { notFound } from '@k8ordo/framework';
import type { PageProps } from '@k8ordo/framework';

export default async function ProductPage({
  params,
}: PageProps<'/products/:id'>) {
  const product = await findProduct(params.id);
  if (product === undefined) notFound();
  return <h1>{product.name}</h1>;
}
vite dev         # renders per request, with Fast Refresh
vite build       # static: dist/client/ is the site
k8ordo generate  # only .k8ordo/, the route table and its types, for tsc in CI

Under mode: 'server' the build is a dist/ that runs on its own — every dependency bundled in, nothing to install where it is deployed — a form posts to a Server Action, and a page receives request, the headers and the cookies, read-only:

vite build
PORT=3000 node dist/server.js
// src/lib/actions.ts
'use server';

import { href } from '@k8ordo/framework';
import { redirect } from '@k8ordo/framework/server';

export async function createTalk(_previous: FormState, formData: FormData) {
  const parsed = parseForm(talkSchema, formData);
  if (!parsed.success) return parsed.state;
  await insertTalk(parsed.data);
  redirect(href('/talks')); // 303 without JavaScript, a navigation with it
}

The built handler, dist/rsc/index.js, is a plain (request: Request) => Promise<Response> that needs nothing from its runtime but AsyncLocalStorage, so Node.js, Bun, Deno and Cloudflare Workers (nodejs_compat) all run it, and vercel() from @k8ordo/framework/vercel writes a build for Vercel.

Under mode: 'static' there is no request, so the build refuses by name whatever needs one — a 'use server' module, a guard.ts, an import of @k8ordo/framework/server — in vite dev as well: this application wants mode: 'server'.

A value paths does not list — a product added after the build — is answered by a fallback.tsx beside the page: the build writes it once as a shell, the layouts in HTML, and the browser draws the page from the URL. The build also writes the _redirects through which Netlify and Cloudflare reach the shell, and vercel() the same rewrites for Vercel — around them, routes of your own: headers on every page, redirects, a rewrite decided by Accept, a proxy to another origin.

AI Agent Documentation

The docs ship inside the package, so an agent always reads the exact version you installed — there is no snapshot to copy or re-sync on upgrade.

Point your agent at them once by pasting this into your project's CLAUDE.md / AGENTS.md:

This application is built with `@k8ordo/framework` (see `mode` in
`vite.config.ts`). Before adding or changing a route, read
`node_modules/@k8ordo/framework/docs/GUIDE.md`, then only the
`docs/references/*.md` it lists that the task needs. `src/routes/` is the
pathname space and holds only page.tsx, layout.tsx, not-found.tsx,
error.tsx, loading.tsx, fallback.tsx, redirect.ts, guard.ts and route.ts;
components go in `src/components/` and every other module (Server Actions,
schemas, state definitions, data, helpers) in `src/lib/`, since a
`_`-prefixed directory there is a URL segment, not a private one. Never
edit `.k8ordo/` — it is generated, with the `Register` augmentations: the
route table's, and `@k8ordo/i18n`'s when `src/i18n.ts` exports the locale
set by the name `locales` (write that one by hand only when the set lives
elsewhere). Import from `@k8ordo/framework` (never
`@k8ordo/router`), and the request API from `@k8ordo/framework/server`,
which `mode: 'static'` refuses. Build links with `href()`; search params
are `@k8ordo/state`'s.

What each surface gives an agent:

| Surface | Where | | -------------------------- | ----------------------------------------------------- | | Design guide (entry point) | node_modules/@k8ordo/framework/docs/GUIDE.md | | Reference docs | node_modules/@k8ordo/framework/docs/references/*.md | | Docs index for LLMs | docs/llms.txt · https://ordo.k8o.me/llms.txt | | Markdown twin on the web | https://ordo.k8o.me/framework/docs/GUIDE.md |

License

MIT License - see LICENSE for details.