Skip to content

Latest commit

 

History

28 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pubflow Native

Ship a full-stack app in the time it takes to write the idea.

Native is not a new runtime. It is Hono + TanStack Router + Vite, with folders so you (or an AI) drop a page and an API file and get something running in minutes — not an afternoon of config. Plenty of frameworks put React and an API in one repo. Native is for the gap from idea to a live URL.

  • npx degit pubflow/native/starter my-app && bun install && bun run dev — page + /api, no config file to invent first.
  • The same Hono fetch runs on Node, Bun, Docker, Nixpacks (Coolify / Railway / a VPS), or Cloudflare Workers (bun run deploy:cf). Workers is one host, not the product. Deploy.
  • Pages cannot import getDb() — the client build fails. Secrets stay on the server by construction.
  • This is for shipping TypeScript apps quickly (many ideas, little time). It is not a replacement for Next on a large product team.

Login is optional. Flowless is a trust layer: it knows who the user is and their role. Native asks Flowless if the session id is valid, then you gate routes and Actions with requireAuth / requireRole. Skip Flowless and Native is still React + Hono.

Anyone can use it. It is not locked to Pubflow products. Stack comparison: Why Native.

Package: @pubflow/native

app/pages/     UI (layout.tsx, index.tsx, [id].tsx)
app/api/       Hono apps → /api/...
app/actions/   functions → POST /api/actions/<id>
app/server.ts  optional — you own fetch
index.html
vite.config.ts plugins: [native()]

Pages cannot read DATABASE_URL. Put queries and secrets in app/api or app/actions. The browser only sees PUBFLOW_PUBLIC_* / VITE_*.

New app: clone starter/

That folder is the app. git clone on the repo URL would pull library, docs, and examples too. Clone only starter/:

npx degit pubflow/native/starter my-app
cd my-app
bun install
bun run dev

npx degit copies starter/ onto my-app/ — same files you see in that GitHub tree, nothing else.

bun run dev          # Vite + Hono (port 3000) — page + /api
bun run build        # client + SSR
bun run start        # Node: dist/server/node.js
bun run start:bun    # Bun: dist/server/bun.js
bun run deploy:cf    # optional — Cloudflare Worker

Node, Docker, and Nixpacks: Deploy. Workers is not required.

The starter (Default) is a complete example: login/dashboard, Tailwind v4, and shadcn already wired (components.json, cn(), @/ → app/, a few UI files). Add more with the official CLI — npx shadcn@latest add dialog — not init -t vite. Delete or ignore auth if you do not use Flowless — Native does not require it. GET / and your own /api/* routes work with no Pubflow services running.

pubflow create native / pubflow start native copies starter/. native-minimal and native-custom-hono copy those example apps (also cloneable with degit). Cloudflare, auth, and shadcn are on Default — examples/cloudflare-worker, examples/with-auth, and examples/shadcn are notes, not templates. Minimal/Custom Hono have no Tailwind; run pubflow add shadcn then npx shadcn add.

Install the CLI (pubflow on npm — bins pubflow and pbfl). Pick the manager you already use:

npm install -g pubflow
pnpm add -g pubflow
yarn global add pubflow
bun add -g pubflow

Without a global install:

npx pubflow start native my-app
npx pubflow create native my-app
pnpm dlx pubflow start native my-app
yarn dlx pubflow create native my-app
bunx pubflow start native my-app

Existing project

npm install or bun add the library. You do not need the rest of Pubflow.

bun add @pubflow/native@latest @tanstack/react-router hono react react-dom
bun add -d vite
// vite.config.ts
import { defineConfig } from 'vite'
import native from '@pubflow/native/vite'

export default defineConfig({
  plugins: [native()],
})
<!-- index.html -->
<div id="root"><!--ssr-outlet--></div>

The plugin injects the client bundle. No main.tsx.

// app/pages/layout.tsx
import type { ReactNode } from 'react'
export default function Layout({ children }: { children: ReactNode }) {
  return <div>{children}</div>
}

// app/pages/index.tsx
export default function HomePage() {
  return <h1>Hello</h1>
}
// app/api/hello.ts → GET /api/hello
import { Hono } from 'hono'
const hello = new Hono()
hello.get('/', (c) => c.json({ hello: true }))
export default hello
// app/actions/ping.ts → POST /api/actions/ping
export async function ping() {
  return { ok: true }
}

GET /health is registered for you. bunx vite, then hit / and /api/hello.

Already on Hono? Keep your routes and mount pages for the rest:

import { pages } from '@pubflow/native/pages'
import { apiFromDir } from '@pubflow/native/api'

const app = new Hono()
app.route('/api', apiFromDir(import.meta.glob('./api/**/*.{ts,js}', { eager: true })))
app.all('*', pages())
export default app

See examples/ — Minimal and Custom Hono are cloneable apps; Cloudflare, with-auth, and shadcn point at Default.

What it is for

  • Minutes from idea to bun run dev: a page in app/pages and a Hono file in app/api
  • Same fetch on Node, Bun, Docker, Nixpacks, or Cloudflare Workers — pick the host
  • Hono + TanStack Router + Vite, not a new runtime
  • Secrets on the server; the client build fails if a page imports getDb()
  • Optional Flowless login: session id in, who + role out; requireAuth / requireRole
  • File routes you already know: layout.tsx, index.tsx, [id].tsx

Native is web. For mobile use pubflow create react-native / Expo. For a non-TypeScript API use Go, Python, or Rust. For an MPA / islands app, HonoX. Details: Why Native.

Pages and API

File Route
app/pages/layout.tsx Nested layout (children)
app/pages/index.tsx /
app/pages/dashboard/index.tsx /dashboard
app/pages/[id].tsx /$id
app/api/users.ts /api/users
app/api/_middleware.ts Middleware for /api/*
app/actions/posts/createPost.ts POST /api/actions/posts.createPost

Default export is the page, layout, or Hono app. You do not write createFileRoute. Generated files live in .pubflow/generated/ (gitignored).

Optional env: browser PUBFLOW_PUBLIC_* or VITE_* (publicEnv()). Server uses normal names (DATABASE_URL, …). pubflow.config.ts is metadata only in v0.1.

Optional Pubflow extras

Flowless is the trust layer: who the user is, their role, and a session id Native can check. Gate /api and Actions with requireAuth / requireRole. Skip it if you do not need login — Native is still React + Hono. See Auth and Why Native.

This repository

Path What it is
library/ npm @pubflow/native
starter/ Default app — auth, Tailwind, shadcn, Cloudflare. npx degit pubflow/native/starter / pubflow create native
examples/minimal, examples/custom-hono-server other cloneable Native apps
examples/cloudflare-worker, examples/with-auth, examples/shadcn, docs/ notes / docs — not templates

Root package.json is private. After a library fix: publish npm, then bump the pin in starter/package.json.

More: docs/

About

Full-stack TypeScript app faster

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages