Web Framework for
Dynamic High-Performance Sites and Apps.
Server-first framework built with TypeScript and Bun.
Zero JavaScript to the client by default.
All TypeScript.
Zero Magic.
No special syntax to learn. No custom file extensions or weird semantics. All TypeScript, all the way down. Hyperspan leverages Bun for incredible speed without the need for a complex compiler.
- check File-based and custom routing included
-
check
Simple HTML templates with
async/await - check Built-in Server Actions with Zod schema validation
- check Dynamic Islands for rich client-side interactivity
import { createRoute } from '@hyperspan/framework';
import { html } from '@hyperspan/html';
export default createRoute().get(async (c) => {
const posts = await fetchPosts();
return html`
<div>
<h1>Posts</h1>
<ul>
${posts.map((post) => html`<li>${post.title}</li>`)}
</ul>
</div>
`;
});
Zero JS Runtime
Most pages don't need hydration. Hyperspan only ships client-side JavaScript for dynamic islands and other client-side scripts you explicitly define.
File & Custom Routing
Built-in file-based and custom routing, full access to the Request context, real middleware with data passing, and full support for streaming HTML content.
Server Actions
Form submissions and data mutations with built-in Zod schema validation, error handling, and responses that update in-place, HTMX-style. Keep all the code and logic on the server where it belongs.
import { createRoute } from '@hyperspan/framework';
import { html } from '@hyperspan/html';
export default createRoute().get(() => {
return html`
<div>
<h1>Async Content Blocks:</h1>
${AsyncBlock(1000, "Resolves after 1 second")}
${AsyncBlock(2000, "Resolves after 2 seconds")}
</div>
`;
});
async function AsyncBlock(waitMs: number, msg: string) {
await sleep(waitMs);
return html`<div>${msg}</div>`;
}
Streaming Content.
Zero Effort.
Streaming responses by default for any template that contains unresolved promises. Send all your static content immediately for better TTFB, then stream in each piece of dynamic content as it's ready.
-
check
Promise values in templates automatically enable streaming (
awaitall content to disable) - check No special "flight" syntax - just streaming HTML
- check Automatic opt-outs for bots, crawlers, and AI
Full Interactivity.
Zero Penalty.
Rich client-side interactivity without full-page hydration.
- check Preact/React Islands for rich client-side interactivity
- check Server-side rendering (SSR) on by default for SEO
- check Lazy loading & hydration options per island
import { html } from '@hyperspan/html';
import { createRoute } from '@hyperspan/framework';
import { renderPreactIsland } from '@hyperspan/plugin-preact';
import ExampleCounter from '~/src/components/example-counter.tsx';
export default createRoute().get(() => {
return html`
<div>
${renderPreactIsland(ExampleCounter, { count: 5 })}
</div>
`;
});
import { createAction } from '@hyperspan/framework/actions';
import { html } from '@hyperspan/html';
import { z } from 'zod/v4';
export default createAction({
name: 'example-action',
schema: z.object({
name: z.string().min(1, 'Name is required'),
}),
})
.form((c, { data, error }) => {
return html`<form method="post">
${error && html`<div class="alert">${error.message}</div>`}
<input type="text" name="name" value="${data?.name}" />
<button type="submit">Submit</button>
</form>`;
})
.post(async (c, { data }) => {
return html`<p>Hello, ${data.name}!</p>`;
});
Server Actions.
Zero Client Logic.
Actions render forms that submit their data back to the server and update the view in-place automatically. Keep all your validation and logic on the server where it belongs.
- check Built-in Zod schema validation
- check Type-safe data and field-specific error messages
- check Automatic error handling and responses
- check Full route middleware support for auth, etc.
Ready to build faster?
Start your next project with Hyperspan in seconds.