Server-side middle-end prioritizing page load times and simplicity.
- Reactive resources
- Server-side async JSX
- Generate dynamic HTML thanks to resources and JS
- Explicit client-side JavaScript boundaries
- Manipulate and attach JS to sent HTML through JSX refs
- TypeScript-first
- Even for JS manipulation
- Industrial-grade navigation (à la Remix)
- Dynamic nested routes
- Actions through
form
s to update reactive resources - Minimum amount of bytes sent over the wire
- Modular design
- Share modules exposing HTML|JS|CSS thanks to the programmatic bundling API
- Extend functionalities and integrate in larger frameworks
- Programmatic workflow
- Optimized bundling (esbuild under the hood)
- Buildless development
- Simple explicit production build
Classic is not a UI library and depends on none, but you can optionally use some. Classic integrates with existing technologies rather than reinventing them.
Typical Classic stack:
- Deno - Runtime, LSP, lint, test, DB...
- Hono - Backend router
- Classic - Reactive HTML/JS/CSS generation
NodeJS support is planned, however we strongly recommend Deno in general.
# Prompts a folder name and creates the template
deno run -r --allow-write=. --allow-net https://raw.githubusercontent.com/ngasull/classic/master/init.ts
Remember: everything runs server-side except what is explicitly wrapped in JS types!
import { db } from "./my-db.ts";
export const YourName = async ({ userId }: { userId: string }) => {
const user = await db.user.find(userId);
return (
<div>
Your name will be {user.name}
</div>
);
};
import { js } from "classic-web/js.ts"
export const YourName = () => {
return (
<div
ref={(div) => js`${div}.innerText = "Your name will be H4CK3D!"`}
>
Your name will be ...
</div>
);
};
import { bundle } from "./bundle.ts";
/*
* Proxied to keep client code explicitly client-side and typed.
* Check the development workflow for more info.
*/
const yourName = bundle.add("./your-name.web.ts");
export const YourName = () => {
return (
<div ref={(div) => yourName.hack(div, "H4CK3D")}>
Your name will be ...
</div>
);
};
// your-name.web.ts
export const hack = (el: HTMLElement, name: string) => {
el.innerText = `Your name will be ${name}`;
};
import type { Bundle } from "classic-web/bundle.ts";
export const yourName = (bundle: Bundle): JSX.Component => {
const yourName = bundle.add<typeof import("./your-name.web.ts")>(
"./your-name.web.ts",
);
return () => {
return (
<div ref={yourName.hack}>
Your name will be ...
</div>
);
};
};
You may check hello-world example