Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 45 additions & 33 deletions content/docs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Overview & Philosophy"
sidebar_position: 1
---

**Gofs** (Go Full Stack) is a lightweight architectural template and CLI for building evergreen web applications. The server is written in Go using only the standard library. Pages are rendered on the server with Go's `html/template`. Interactivity is delivered through small, standards-based web components written with [Lit](https://lit.dev). Data lives in PostgreSQL and is queried with plain SQL through [sqlc](https://sqlc.dev).
**Gofs** (Go Full Stack) is a lightweight architectural template and CLI for building evergreen web applications. The server is written in Go using only the standard library. Pages are rendered on the server with Go's `html/template`. Interactivity is delivered through standards-based **Web Components** (Custom Elements and Declarative Shadow DOM). Developers can author components using pure native browser APIs or lightweight micro-libraries rooted in web components, without proprietary framework lock-in. Data lives in PostgreSQL and is queried with plain SQL through [sqlc](https://sqlc.dev).

Gofs is designed around a single guiding premise: **minimize runtime dependencies and build on stable, backward-compatible standards.** It leverages Go's backward compatibility promise on the server and the web platform's permanence in the browser to deliver applications that remain maintainable for decades without relentless upgrade churn.

Expand All @@ -27,8 +27,8 @@ While that initial stack proved that server-driven web apps could replace comple
2. **Web Components & Declarative Shadow DOM (DSD)**:
Browser standards evolved significantly. Custom Elements are universally supported in every browser engine without polyfills. Crucially, **Declarative Shadow DOM (`<template shadowrootmode="open">`)** is now Baseline Widely Available across all major browsers. DSD allows the Go server to output encapsulated shadow roots directly in server-rendered HTML. Components gain true style and DOM encapsulation with zero client-side JavaScript execution required for initial render and zero layout shift.

3. **Lit as a Standards-Based Micro-Library**:
Rather than attempting to force "Go everywhere" or stretching HTML attributes into an ad-hoc client application, modern web standards provide custom elements. [Lit](https://lit.dev) provides a featherweight (~5 KB) reactive layer on top of native Custom Elements, adding reactive properties and tagged template literals (`html`\``...`\``). Lit requires no bundler, no compile step, and zero proprietary framework runtime. It vendors as a single file, serves directly from the Go binary, and natively hydrates Declarative Shadow DOM rendered by Go templates.
3. **Web Standards Over Framework Lock-In**:
Rather than attempting to force "Go everywhere" or stretching HTML attributes into an ad-hoc client application, modern web standards provide native **Custom Elements**. Because Custom Elements are a native W3C browser standard, they provide universal interoperability. You are never locked into an ephemeral framework ecosystem. Developers can write pure vanilla custom elements using native browser APIs, or choose minimal authoring libraries rooted strictly in web components (such as Lit or FAST). These tools are not monolithic applications that take over your page—they are merely thin ergonomic helpers around standard Custom Elements, requiring no bundlers, compiling to standard ES modules, serving directly from the Go binary, and natively hydrating Declarative Shadow DOM rendered by standard Go templates.

4. **AI Eliminates the "Cumbersome HTML" Penalty**:
Historically, developers justified complex template DSLs (such as `templ` or JSX) or heavy framework abstractions because hand-authoring raw HTML, repetitive form structures, and Go's `html/template` blocks felt verbose and cumbersome.
Expand All @@ -41,24 +41,20 @@ While that initial stack proved that server-driven web apps could replace comple

In modern software engineering, adding a dependency is often treated as "free functionality." In reality, every external runtime dependency is an ongoing liability.

```
┌─────────────────────────────────────────────────────────────┐
│ The Dependency Tax │
│ │
│ [ New Dependency ] ──► [ Transitive Tree Explodes ] │
│ │ │
│ ▼ │
│ [ Security Advisories ] │
│ │ │
│ ▼ │
│ [ Breaking Changes ] │
│ │ │
│ ▼ │
│ [ Costly Upgrade Cycles ] │
│ │ │
│ ▼ │
│ 80% Time Spent "Standing Still" │
└─────────────────────────────────────────────────────────────┘
```mermaid
flowchart TD
A["New Dependency Added"] --> B["Transitive Tree Explodes<br/>(Hundreds of Packages)"]
B --> C["Continuous Security Advisories & CVEs"]
C --> D["Upstream Breaking Changes & Deprecations"]
D --> E["Costly Migration & Rewrite Cycles"]
E --> F["80% Engineering Time Spent 'Standing Still'"]

style A fill:#1e293b,stroke:#3b82f6,stroke-width:2px,color:#f8fafc
style B fill:#1e293b,stroke:#eab308,stroke-width:1px,color:#f8fafc
style C fill:#1e293b,stroke:#f97316,stroke-width:1px,color:#f8fafc
style D fill:#1e293b,stroke:#ef4444,stroke-width:1px,color:#f8fafc
style E fill:#1e293b,stroke:#dc2626,stroke-width:2px,color:#f8fafc
style F fill:#450a0a,stroke:#ef4444,stroke-width:2px,color:#fca5a5
```

### The Upgrade Treadmill & "Standing Still" Costs
Expand All @@ -82,7 +78,7 @@ A typical single-page application using npm frequently pulls in **thousands of t
Gofs combats this at the architectural root:
- **No Node.js, npm, or Bundlers**: A gofs project contains no `package.json` and no `node_modules`.
- **Zero Runtime Dependencies**: The Go backend depends only on Go's standard library. Even the database layer (`sqlc`) produces plain `database/sql` code with zero third-party runtime dependencies.
- **Vendored, Checksummed Client Assets**: The only browser libraries used (Lit and its Task controller) are vendored as single static files, pinned, and checksummed in `.gofs/vendor.json`, served directly from the embedded Go binary with immutable cache headers.
- **Vendored, Checksummed Client Assets**: Any client-side scripts or web component helpers are vendored as standalone, pinned, and checksummed static files in `.gofs/vendor.json` and served directly from the embedded Go binary with immutable cache headers—bypassing npm entirely.

Eliminating third-party runtime dependencies shrinks the software attack surface to near zero.

Expand All @@ -107,17 +103,33 @@ Gofs grounds its frontend architecture directly in web standards:
- **Modern CSS Baseline**: Modern CSS provides nesting, cascade layers, CSS custom properties (variables), and container queries natively. There is no need for CSS preprocessors, PostCSS, or bundler configurations.
- **Baseline Policy**: Gofs adheres to the [Web Baseline](https://web.dev/baseline) standard. *Widely available* features are used freely, *Newly available* features include graceful fallbacks, and *Limited availability* features require explicit justification.

```
┌─────────────────────────────────────────────────────────────┐
│ The Gofs Evergreen Stack │
│ │
│ SERVER: Go Standard Library (Go 1 Compatibility Promise) │
│ DATABASE: sqlc (Plain SQL ──► database/sql, 0 Runtime) │
│ TEMPLATES: html/template + Declarative Shadow DOM (DSD) │
│ FRONTEND: Web Components (Custom Elements) + Lit (~5 KB) │
│ STYLING: Modern Baseline CSS (Nesting, Variables, Layers) │
│ TOOLING: AI-Assisted, Zero Build Step, Zero npm │
└─────────────────────────────────────────────────────────────┘
```mermaid
flowchart TD
subgraph STACK["The Gofs Evergreen Architecture"]
direction TB
S["<b>SERVER</b><br/>Go Standard Library (Go 1 Compatibility Promise)"]
D["<b>DATABASE</b><br/>sqlc (Plain SQL ➔ database/sql, Zero Runtime)"]
T["<b>TEMPLATES & SSR</b><br/>html/template + Declarative Shadow DOM (DSD)"]
F["<b>FRONTEND & INTERACTIVITY</b><br/>Web Components (W3C Custom Elements, Framework-Agnostic)"]
C["<b>STYLING</b><br/>Modern Baseline CSS (Variables, Nesting, Scoped Styles)"]
A["<b>TOOLING & VELOCITY</b><br/>AI Coding Assistants + Zero Build Step + Zero npm"]
end

S --> T
D --> S
T --> F
F --> C
A -. Accelerates .-> S
A -. Accelerates .-> T
A -. Accelerates .-> F

style STACK fill:#0f172a,stroke:#334155,stroke-width:2px,color:#94a3b8
style S fill:#1e293b,stroke:#0ea5e9,stroke-width:2px,color:#f8fafc
style D fill:#1e293b,stroke:#10b981,stroke-width:2px,color:#f8fafc
style T fill:#1e293b,stroke:#8b5cf6,stroke-width:2px,color:#f8fafc
style F fill:#1e293b,stroke:#f59e0b,stroke-width:2px,color:#f8fafc
style C fill:#1e293b,stroke:#ec4899,stroke-width:2px,color:#f8fafc
style A fill:#1e293b,stroke:#64748b,stroke-width:2px,color:#f8fafc
```

---
Expand Down
27 changes: 12 additions & 15 deletions content/docs/backend/sqlc.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,18 @@ Traditional Object-Relational Mapping (ORM) frameworks (such as GORM, Hibernate,

In contrast, **sqlc bundles zero runtime dependencies**. The code generated by sqlc imports only Go's standard library packages (`database/sql`, `context`, and `encoding/json`). It introduces zero third-party packages to your production binary.

```
┌─────────────────────────────────────────────────────────────┐
│ sqlc Zero-Dependency Flow │
│ │
│ Schema (migrations.sql) ─┐ │
│ ├──► [ sqlc compile check ] │
│ Queries (queries.sql) ─┘ │ │
│ ▼ │
│ Generated Go Code │
│ (Imports ONLY standard database/sql!) │
│ │ │
│ ▼ │
│ Committed to Git │
│ (Builds with pure Go compiler, 0 deps!)│
└─────────────────────────────────────────────────────────────┘
```mermaid
flowchart TD
S["Database Schema<br/><code>migrations.sql</code>"] --> C["<b>sqlc compile check</b><br/>(Validates SQL syntax & types against schema)"]
Q["Raw SQL Queries<br/><code>queries.sql</code>"] --> C
C --> G["<b>Generated Type-Safe Go Code</b><br/>(Imports ONLY standard <code>database/sql</code>)"]
G --> R["<b>Committed to Git Repository</b><br/>(Builds with pure Go toolchain, 0 runtime dependencies)"]

style S fill:#1e293b,stroke:#0ea5e9,stroke-width:2px,color:#f8fafc
style Q fill:#1e293b,stroke:#0ea5e9,stroke-width:2px,color:#f8fafc
style C fill:#1e293b,stroke:#eab308,stroke-width:2px,color:#f8fafc
style G fill:#1e293b,stroke:#10b981,stroke-width:2px,color:#f8fafc
style R fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#a7f3d0
```

### 2. Committed, Standalone Go Code
Expand Down
48 changes: 33 additions & 15 deletions content/docs/core/rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,37 @@ Modern AI coding assistants completely neutralize this friction. AI assistants e

Gofs supports two complementary patterns for building web component islands: **Light DOM Islands** and **Declarative Shadow DOM (DSD) Islands**.

```
┌────────────────────────────────────────────────────────────────────────┐
│ Island Architecture │
│ │
│ ┌────────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ Light DOM Island │ │ Declarative Shadow DOM (DSD)│ │
│ ├────────────────────────────────┤ ├─────────────────────────────┤ │
│ │ • Inherits global app.css │ │ • Strict style encapsulation│ │
│ │ • Direct access to DOM childs │ │ • Native SSR with <template>│ │
│ │ • Ideal for forms, buttons, │ │ • Reusable widgets, slots │ │
│ │ and in-page interactions │ │ • Zero layout shift / FOUC │ │
│ └────────────────────────────────┘ └─────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
```mermaid
flowchart LR
subgraph ISLANDS["Island Architecture: Two Complementary Patterns"]
direction LR
subgraph LIGHT["Light DOM Island"]
direction TB
L1["• Inherits global app.css"]
L2["• Direct access to DOM children"]
L3["• Ideal for forms & in-page interactions"]
L4["• Zero JS required for progressive enhancement"]
end
subgraph DSD["Declarative Shadow DOM (DSD)"]
direction TB
D1["• Strict style & DOM encapsulation"]
D2["• Native SSR with &lt;template shadowrootmode&gt;"]
D3["• Reusable component widgets & &lt;slot&gt; projection"]
D4["• Zero layout shift (CLS) & zero FOUC"]
end
end

style ISLANDS fill:#0f172a,stroke:#334155,stroke-width:2px,color:#94a3b8
style LIGHT fill:#1e293b,stroke:#3b82f6,stroke-width:2px,color:#f8fafc
style DSD fill:#1e293b,stroke:#8b5cf6,stroke-width:2px,color:#f8fafc
style L1 fill:#0f172a,stroke:none,color:#cbd5e1
style L2 fill:#0f172a,stroke:none,color:#cbd5e1
style L3 fill:#0f172a,stroke:none,color:#cbd5e1
style L4 fill:#0f172a,stroke:none,color:#cbd5e1
style D1 fill:#0f172a,stroke:none,color:#cbd5e1
style D2 fill:#0f172a,stroke:none,color:#cbd5e1
style D3 fill:#0f172a,stroke:none,color:#cbd5e1
style D4 fill:#0f172a,stroke:none,color:#cbd5e1
```

### 1. Light DOM Islands (Default)
Expand All @@ -115,7 +133,7 @@ In a Light DOM island, the server renders standard HTML directly inside the cust
</todo-list>
```

In the component JavaScript, we tell Lit to render into the light DOM rather than creating a shadow root:
In component JavaScript (here illustrated using Lit as a lightweight custom element helper), we can render directly into the light DOM rather than creating a shadow root:

```js
export class TodoList extends LitElement {
Expand Down Expand Up @@ -167,7 +185,7 @@ DSD is a native browser standard (Baseline Widely Available) that allows the ser
#### Why DSD is a Major Leap Forward:
- **Instant Paint Without JavaScript**: Browsers immediately render the encapsulated shadow DOM while streaming the HTML, eliminating the Flash of Unstyled Content (FOUC) and Cumulative Layout Shift (CLS) historically associated with client-rendered web components.
- **True Server-Side Rendering (SSR)**: The Go server renders the entire component UI, while CSS scoping remains 100% enforced by the browser engine.
- **Native Lit Hydration**: When Lit loads on the client, it automatically discovers the existing shadow root rendered by DSD, seamlessly adopting the server-rendered DOM tree without recreating elements or flashing.
- **Native Web Component Hydration**: When client component scripts load, custom element classes (such as Lit or vanilla custom elements) automatically discover the existing shadow root rendered by DSD, seamlessly adopting the server-rendered DOM tree without recreating elements or flashing.

---

Expand Down
2 changes: 1 addition & 1 deletion content/docs/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ gofs init github.com/myorg/myapp myfolder
go tool gofs init github.com/myorg/myapp
```

The generated project is a complete, runnable app. It contains a Go server, a page layout, a vendored copy of Lit, an example component, and a `sqlc.yaml` ready for your first package. There is no `package.json` and nothing to `npm install`.
The generated project is a complete, runnable app. It contains a Go server, a page layout, vendored web component helpers, an example component, and a `sqlc.yaml` ready for your first package. There is no `package.json` and nothing to `npm install`.

## 3. Run the project

Expand Down
3 changes: 3 additions & 0 deletions layouts/_default/_markup/render-codeblock-mermaid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="mermaid" style="display: flex; justify-content: center; margin: var(--snice-spacing-xl) 0; overflow-x: auto;">
{{ .Inner | safeHTML }}
</div>
18 changes: 18 additions & 0 deletions layouts/partials/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,21 @@
</ul>
</div>
</footer>

<script type="module">
if (document.querySelector('.mermaid')) {
const { default: mermaid } = await import('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs');
mermaid.initialize({
startOnLoad: true,
theme: 'dark',
themeVariables: {
darkMode: true,
background: '#191919',
primaryColor: '#3b82f6',
primaryTextColor: '#f4f4f5',
primaryBorderColor: '#3f3f46',
lineColor: '#a1a1aa'
}
});
}
</script>
Loading