THE FULL-STACK GO WEB FRAMEWORK

Less setup.
More takeoff.

The productivity of Rails. The simplicity of Go.
One thoughtful framework for your next big idea.

From your first route to your data, views, and storage.
All the pieces, already connected.

your-next-big-idea /GO
// A real API. A little Go.
func IndexAction(c *gin.Context) {
    posts, err := repo.FindBy[models.Post](
        sql.H{"active": true},
    )

    if err != nil {
        render.Error(c, err)
        return
    }

    render.OK(c, posts)
}
SMALL CODE. BIG POSSIBILITIES.UTF-8
Familiar conventions. Refreshingly Go.
A solid foundation.
From the first line.
Go
Gin
templ
PostgreSQL
MySQL 8
SQLite

01 / A FRAMEWORK THAT FITS TOGETHER

Your stack.
Already on the same page.

Stop assembling the essentials.
Start building what makes your app yours.

01

A data layer that speaks Go

Generics-based CRUD, eager loading, joins, and transactions. Pair typed repositories with an expressive, dialect-aware SQL builder.

Explore the repository
02

HTML, with a Go mindset

Compose type-safe, server-rendered views with templ. Keep your pages and your API in the same language, in the same application.

Meet templ views
03

A head start, built in

Generate APIs, actions, models, and services from the CLI. Evolve your schema with migrations and explore your data in the REPL.

Find your workflow
04

Files at home. Or in the cloud.

One storage API for local files, Amazon S3, Cloudflare R2, and Tencent COS. Change your backend through configuration.

Explore storage
05

Ready for real time

Gin handles your HTTP routes. Built-in WebSocket pub/sub connects your clients. Add Redis when your application needs it.

See the endpoints
06

A straightforward way to ship

Build a self-contained Go binary or a Docker image. Pure-Go SQLite needs no CGO. Deploy under a sub-path behind your reverse proxy.

Take it to production

Use the whole framework. Or just the parts you love. Reusable libraries under lib/, a runnable application skeleton, and room to make it your own.

02 / YOUR DATA, YOUR CHOICE

Different databases.
Same familiar code.

Start small with SQLite. Connect to PostgreSQL or MySQL 8. Airway infers the driver from your connection string, so your basic CRUD code stays with you.

See database configuration
.envONE CONFIGURATION CHANGE
# Local development, zero database services.
DSN="sqlite://./tmp/airway.db"
// Your application code stays familiar.repo.FindBy[Post](sql.H{"active": true})

Basic CRUD is portable. Some advanced SQL helpers are PostgreSQL-specific.

03 / THE FRONTEND, WITHOUT NODE.JS

Islands of interactivity.
One binary, start to finish.

Pages stay server-rendered with templ — structure, SEO, and first paint included. Where a page needs to react, drop in an island: a Preact component mounted on one small spot of the page, seeded with props from your Go action. Fetching, resolving, bundling, and serving npm packages happens inside the airway binary itself.

  • templ renders the skeleton. Pages paint fully without JavaScript; islands hydrate only the spots that need to react.
  • Islands own the interactivity. Props ride along as JSON next to the mount point — no client-side fetch before first render.
  • esbuild, linked as a Go library. Local dev rebuilds in memory with livereload; production bundles embed in the binary via go:embed.
  • airway-ui on a preact/compat base. Logic from the React ecosystem, a visual layer built in-house — live reference at /ui.
Read the frontend guide
// In any templ view — an island, seeded server-side:
@assets.Island("chart", map[string]any{
    "points": []int{4, 8, 15}),

// What ships to the browser:
<div data-island="chart"></div>
<script type="application/json" id="island-data-1">
    {"points":[4, 8, 15]}
</script>

// The runtime scans data-island nodes and mounts the
// component with the adjacent JSON as props.
LIVE ON THIS PAGE — SORT, PAGE, CLICK A ROW

Outgrow the islands? Split the frontend into its own app and keep Airway as your JSON API — the escape hatch is part of the design.

04 / CLEAR FOR TAKEOFF

Your next project
starts here.

A few commands. A working application.
And a whole lot of possibility.

  1. 01
    Make it yours

    Clone Airway and copy the example config.

  2. 02
    Pick your database

    Uncomment the SQLite DSN in your .env file.

  3. 03
    You’re ready to Go

    Start the app and open localhost:1900.

Read the complete setup guide
Quick start
# 1. Get the code
git clone https://github.com/daqing/airway.git
cd airway
cp .env.example .env

# 2. In .env, uncomment the SQLite DSN:
# DSN="sqlite://./tmp/airway.db"

# 3. Start your application
AIRWAY_ENV=local go run .

Requires Go 1.27.1 or later · Live reload with just dev

OPEN SOURCE. OPEN POSSIBILITIES.

Good things are built together.

Read the code. Open an issue. Make your first contribution.
There’s a place for your ideas in Airway.

Find us on GitHub