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

@ovenx/oven

v0.1.1

Published

A full-stack web framework powered by Bun - Next.js style routing with blazing fast performance

Downloads

85

Readme

🔥 Oven Framework

A Next.js-style full-stack web framework powered by Bun runtime.

Build modern web applications with file-based routing, server-side rendering, and API routes — up to 4x faster than Node.js.

npm version License: MIT

Demo: https://oven-drab.vercel.app


✨ Features

| Feature | Description | |---------|-------------| | 📁 App Router | Next.js-style file-based routing with nested layouts | | ⚡ Blazing Fast | Powered by Bun runtime, up to 4x faster than Node.js | | 🎨 SSR Built-in | Server-side rendering out of the box | | 🔌 API Routes | Create RESTful APIs with route.ts files | | 📦 TypeScript First | Full TypeScript support with type safety | | 🧩 Nested Layouts | Compose UIs with nested layouts and route groups | | 🚀 Zero Config | Start building immediately, no complex setup | | 🐳 Docker Ready | Production-ready Docker configuration included |


🚀 Quick Start

Create a New Project

# Using npx
npx create-oven my-app

# Or using bunx
bunx create-oven my-app

# Navigate to project
cd my-app

# Install dependencies
bun install

# Start development server
bun run dev

Open http://localhost:3000 to see your app.


📁 Project Structure

my-app/
├── app/
│   ├── layout.tsx          # Root layout
│   ├── page.tsx            # Home page (/)
│   ├── loading.tsx         # Loading UI
│   ├── error.tsx           # Error boundary
│   ├── not-found.tsx       # 404 page
│   │
│   ├── about/
│   │   └── page.tsx        # About page (/about)
│   │
│   ├── blog/
│   │   ├── layout.tsx      # Blog layout
│   │   ├── page.tsx        # Blog list (/blog)
│   │   └── [slug]/
│   │       └── page.tsx    # Blog post (/blog/:slug)
│   │
│   ├── api/
│   │   └── users/
│   │       ├── route.ts    # API endpoint (/api/users)
│   │       └── [id]/
│   │           └── route.ts # API endpoint (/api/users/:id)
│   │
│   └── (dashboard)/        # Route group (no URL segment)
│       ├── layout.tsx      # Dashboard layout
│       └── dashboard/
│           └── page.tsx    # Dashboard (/dashboard)
│
├── public/                 # Static files
├── components/             # Shared components
├── lib/                    # Utilities
├── oven.config.ts          # Configuration
└── package.json

📄 File Conventions

| File | Purpose | |------|---------| | layout.tsx | Shared UI wrapper for a route segment and its children | | page.tsx | Unique UI for a route, makes the route publicly accessible | | loading.tsx | Loading UI shown while page content loads | | error.tsx | Error UI boundary for a segment and its children | | not-found.tsx | UI shown when a route is not found (404) | | route.ts | API endpoint handler (GET, POST, PUT, DELETE, etc.) |


🛣️ Routing

Pages

Create a page.tsx file in any folder under app/ to create a route:

// app/page.tsx → /
// app/about/page.tsx → /about
// app/blog/[slug]/page.tsx → /blog/:slug

import type { PageProps, Metadata } from './types';

export const metadata: Metadata = {
  title: 'Home',
  description: 'Welcome to my app',
};

export default function HomePage({ searchParams }: PageProps) {
  return `
    <div>
      <h1>Hello, Oven! 🔥</h1>
      <p>Build amazing apps with Bun</p>
    </div>
  `;
}

Dynamic Routes

Use brackets [param] for dynamic segments:

// app/blog/[slug]/page.tsx

export default function BlogPost({ params }: PageProps) {
  return `
    <article>
      <h1>Post: ${params.slug}</h1>
    </article>
  `;
}

Catch-All Routes

Use [...param] for catch-all segments:

// app/docs/[...path]/page.tsx → /docs/a/b/c

export default function Docs({ params }: PageProps) {
  const path = params.path; // "a/b/c"
  return `<div>Path: ${path}</div>`;
}

🧩 Layouts

Layouts wrap pages and persist across navigations:

// app/layout.tsx

import type { LayoutProps } from './types';

export default function RootLayout({ children }: LayoutProps) {
  return `
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My App</title>
      </head>
      <body>
        <nav>
          <a href="/">Home</a>
          <a href="/about">About</a>
        </nav>
        <main>${children}</main>
      </body>
    </html>
  `;
}

Nested Layouts

Each route segment can have its own layout:

// app/blog/layout.tsx

export default function BlogLayout({ children }: LayoutProps) {
  return `
    <div class="blog-container">
      <aside>Blog Sidebar</aside>
      <main>${children}</main>
    </div>
  `;
}

🔌 API Routes

Create API endpoints using route.ts files:

// app/api/users/route.ts

// GET /api/users
export async function GET(request: Request) {
  const users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' },
  ];
  return Response.json(users);
}

// POST /api/users
export async function POST(request: Request) {
  const body = await request.json();
  const newUser = { id: Date.now(), ...body };
  return Response.json(newUser, { status: 201 });
}

// PUT, PATCH, DELETE also supported
export async function DELETE(request: Request) {
  return Response.json({ message: 'Deleted' });
}

Dynamic API Routes

// app/api/users/[id]/route.ts

export async function GET(
  request: Request,
  { params }: { params: { id: string } }
) {
  const userId = params.id;
  return Response.json({ id: userId, name: 'User ' + userId });
}

📦 Route Groups

Use parentheses (name) to organize routes without affecting the URL:

app/
├── (marketing)/
│   ├── layout.tsx      # Marketing layout
│   ├── page.tsx        # / (home)
│   └── about/
│       └── page.tsx    # /about
│
└── (dashboard)/
    ├── layout.tsx      # Dashboard layout (different from marketing)
    └── dashboard/
        └── page.tsx    # /dashboard

🏷️ Metadata

Define metadata for SEO:

// Static metadata
export const metadata: Metadata = {
  title: 'My Page',
  description: 'Page description',
  keywords: ['oven', 'bun', 'framework'],
  openGraph: {
    title: 'My Page',
    description: 'Page description',
    type: 'website',
  },
};

// Dynamic metadata
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
  const post = await getPost(params.slug);
  return {
    title: post.title,
    description: post.excerpt,
  };
}

⚙️ Configuration

Create oven.config.ts in your project root:

import type { OvenConfig } from 'oven';

const config: OvenConfig = {
  // Server port
  port: 3000,

  // App directory
  appDir: 'app',

  // Public directory for static files
  publicDir: 'public',

  // Enable/disable features
  features: {
    ssr: true,
    streaming: true,
  },
};

export default config;

📖 TypeScript Types

// Page props
interface PageProps {
  params: Record<string, string>;
  searchParams: Record<string, string>;
}

// Layout props
interface LayoutProps {
  children: string;
  params: Record<string, string>;
}

// Metadata
interface Metadata {
  title?: string | { default: string; template?: string };
  description?: string;
  keywords?: string[];
  openGraph?: {
    title?: string;
    description?: string;
    type?: string;
    images?: string[];
  };
}

🐳 Docker Deployment

Dockerfile

FROM oven/bun:1 AS builder
WORKDIR /app
COPY package.json bun.lockb* ./
RUN bun install --frozen-lockfile
COPY . .

FROM oven/bun:1-slim AS production
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/src ./src
COPY --from=builder /app/app ./app
COPY --from=builder /app/bin ./bin
COPY --from=builder /app/package.json ./
COPY --from=builder /app/oven.config.ts ./
COPY --from=builder /app/tsconfig.json ./
COPY --from=builder /app/public* ./public/

ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000

CMD ["bun", "run", "bin/oven.js", "start"]

Docker Compose

version: '3.8'
services:
  oven:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - PORT=3000

Run with Docker

# Build and run
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down

▲ Vercel Deployment

1. Add vercel.json

{
  "buildCommand": "bun run build:vercel",
  "outputDirectory": "dist",
  "installCommand": "curl -fsSL https://bun.sh/install | bash && ~/.bun/bin/bun install",
  "framework": null
}

2. Add build script

{
  "scripts": {
    "build:vercel": "bun run scripts/build-static.ts"
  }
}

3. Deploy

vercel --prod

🆚 Oven vs Next.js

| Feature | Oven 🔥 | Next.js | |---------|---------|---------| | Runtime | Bun | Node.js | | Cold Start | ~0ms | ~200ms | | Install Time | ~1s | ~30s | | TypeScript | Native | Compiled | | Bundle Size | Smaller | Larger | | Speed | 4x faster | Baseline |


💻 CLI Commands

# Create new project
npx create-oven my-app

# Development server (with hot reload)
bun run dev

# Build for production
bun run build

# Start production server
bun run start

🗺️ Roadmap

  • [x] v0.1.0 — Initial release with core features
  • [ ] v0.2.0 — React/JSX component support
  • [ ] v0.3.0 — Edge runtime (Cloudflare Workers)
  • [ ] v0.4.0 — Middleware support
  • [ ] v1.0.0 — Stable production release

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

# Clone the repository
git clone https://github.com/oven-ttta/oven-framework.git

# Install dependencies
cd oven-framework
bun install

# Start development
bun run dev

📄 License

MIT License - see the LICENSE file for details.


🔗 Links

| Resource | URL | |----------|-----| | npm | npmjs.com/package/create-oven | | GitHub | github.com/oven-ttta/oven-framework | | Demo | oven-drab.vercel.app |