philosophy.html

168 lines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
{{template "main.html" .}}

{{define "title"}}Philosophy — Congo{{end}}
{{define "description"}}Why Congo vendors source, distributes itself, uses SQLite in production, and renders HTML on the server. Ideas that sound weird until they don't.{{end}}

{{define "content"}}
<div class="max-w-3xl mx-auto px-6 py-16">
    <h1 class="text-3xl md:text-4xl font-bold tracking-tight mb-3">Ideas That Sound Weird Until They Don't</h1>
    <p class="text-body text-base mb-16">
        Congo makes choices most frameworks avoid. Each one optimizes for developer ownership, simplicity, and longevity.
    </p>

    <div class="space-y-0">

        <!-- Vendored Source -->
        <section class="pb-16">
            <h2 class="text-xl font-bold tracking-tight mb-4">Vendored Source, Not Dependencies</h2>
            <p class="text-body leading-relaxed mb-4">
                When you run <code class="text-accent">congo init</code>, the entire framework is copied into your project
                as regular Go files in <code class="text-accent">internal/</code>. Not downloaded from a registry. Not fetched
                at build time. Copied. You can read every line, modify anything, and your project compiles with zero network access.
            </p>
            <p class="text-body leading-relaxed mb-4">
                The conventional approach — importing packages from registries — creates invisible dependencies on infrastructure
                you don't control. Registries go down. Maintainers delete packages. Major versions introduce breaking changes
                that cascade through your dependency tree. These aren't hypothetical risks. They happen regularly.
            </p>
            <div class="quote-bar">
                <p>Your project's framework code lives in your repo. The dependencies it pulls in — SQLite, JWT, UUID generation — are small, stable libraries. Everything else is source code you own.</p>
            </div>
            <p class="text-body leading-relaxed">
                This also means you can understand your framework. It's a few thousand lines of Go. Open the files,
                read the code, see how routing works, how the ORM builds queries, how templates are parsed.
                There's no version to pin, no changelog to track, no upgrade to break things. It's your code now.
                See the <a href="/guide#packages" class="text-accent hover:text-bright transition-colors" hx-boost="true">five packages</a> that make up the framework.
            </p>
        </section>

        <!-- Self-Hosting Distribution -->
        <section class="section-divide py-16">
            <h2 class="text-xl font-bold tracking-tight mb-4">The Website Is the Distribution</h2>
            <p class="text-body leading-relaxed mb-4">
                Congo is not on GitHub. You're reading this on a Congo application that serves its own source code.
                Every file — the framework, the CLI, the scaffold templates, this website — is browsable at
                <a href="/source" class="text-accent hover:text-bright transition-colors" hx-boost="true">/source</a>.
            </p>
            <p class="text-body leading-relaxed mb-4">
                If you already have Congo, run <code class="text-accent">congo source</code> to extract the complete source tree.
                This gives you everything needed to rebuild the CLI from scratch. Congo carries its own DNA inside every binary.
            </p>
            <div class="quote-bar">
                <p>Congo reproduces itself. Every binary contains the full source tree. Every project contains the full framework. No single platform controls distribution.</p>
            </div>
            <p class="text-body leading-relaxed">
                This isn't about avoiding GitHub. It's about proving that software can distribute itself without depending on
                any particular platform. The binary is the package manager. The website is the repository. The source is always available.
            </p>
        </section>

        <!-- AI-First -->
        <section class="section-divide py-16">
            <h2 class="text-xl font-bold tracking-tight mb-4">Frameworks Should Teach AI About Themselves</h2>
            <p class="text-body leading-relaxed mb-4">
                Most frameworks are passive when it comes to AI. You paste code into ChatGPT, and it guesses at your patterns.
                It hallucinates APIs. It suggests conventions from different frameworks. You spend more time correcting the AI
                than you saved by using it.
            </p>
            <p class="text-body leading-relaxed mb-4">
                Congo takes an active approach. <code class="text-accent">congo claude</code> launches Claude Code with a complete
                framework reference injected into the session — controller patterns, model API, template conventions, database
                conventions, deployment patterns. The AI doesn't guess. It knows.
            </p>
            <div class="quote-bar">
                <p>The framework is designed to be understood — by humans and by machines. Small API surface, consistent patterns, explicit conventions. Good for reading, good for AI.</p>
            </div>
            <p class="text-body leading-relaxed">
                This works because Congo is small and consistent. Five packages, a handful of patterns, no magic.
                When the AI can read and understand the entire framework, it writes code that fits. When the framework
                provides its own documentation to the AI, every developer gets an expert pair programmer for free.
            </p>
        </section>

        <!-- HTMX Over SPAs -->
        <section class="section-divide py-16">
            <h2 class="text-xl font-bold tracking-tight mb-4">Server-Rendered HTML, Not Single-Page Apps</h2>
            <p class="text-body leading-relaxed mb-4">
                The last decade of web development pushed everything to the client. React, Vue, Svelte — frameworks
                that run in the browser, manage their own state, and communicate with the server through JSON APIs.
                This added enormous complexity: build pipelines, hydration, serialization boundaries, duplicated
                validation, bundle optimization, client-side routing.
            </p>
            <p class="text-body leading-relaxed mb-4">
                Congo uses HTMX. The server renders HTML. HTMX swaps it into the page. No client-side state,
                no build pipeline for views, no API layer between your app and your UI. Your web application is
                a Go program that returns HTML. When you need complex interactivity — a code editor, a chart,
                a drag-and-drop interface — Congo supports React islands that mount into server-rendered pages.
            </p>
            <div class="quote-bar">
                <p>Your web app is a Go program that returns HTML. That's the whole architecture. HTMX for interactivity. React islands when you genuinely need them. Nothing else.</p>
            </div>
            <p class="text-body leading-relaxed">
                This isn't a regression. It's a correction. The industry is moving back to server rendering —
                Rails 8, Phoenix LiveView, Django + HTMX, even Next.js with Server Components. Congo starts there.
            </p>
        </section>

        <!-- SQLite in Production -->
        <section class="section-divide py-16">
            <h2 class="text-xl font-bold tracking-tight mb-4">SQLite in Production</h2>
            <p class="text-body leading-relaxed mb-4">
                The conventional wisdom says production databases need a separate server — PostgreSQL, MySQL,
                managed RDS. This adds operational complexity, network latency, connection pooling, and another
                thing that can go down at 3 AM.
            </p>
            <p class="text-body leading-relaxed mb-4">
                Congo uses SQLite. Your database is a file. Reads come from memory (nanosecond latency — faster
                than any cache). N+1 queries are not a performance problem when each query takes nanoseconds.
                For development, it's in-memory. For production, it's a file on disk with WAL mode. When you
                need distributed reads, Congo supports <a href="https://turso.tech/libsql" class="text-accent hover:text-bright transition-colors" target="_blank" rel="noopener">LibSQL</a> embedded replicas by Turso — local SQLite synced from a remote primary.
                See how it works in the <a href="/guide" class="text-accent hover:text-bright transition-colors" hx-boost="true">guide</a>.
            </p>
            <div class="quote-bar">
                <p>N+1 queries are not a problem when your database reads from memory. No connection pooling. No database server. No network hop. Just a file.</p>
            </div>
            <p class="text-body leading-relaxed">
                Rails 8 validated this approach in 2024 by shipping Solid Cache, Solid Queue, and Solid Cable —
                all supporting SQLite as a backend. If 37signals trusts SQLite for production infrastructure, it's good enough for your app.
            </p>
        </section>

        <!-- Single Binary -->
        <section class="section-divide py-16">
            <h2 class="text-xl font-bold tracking-tight mb-4">Single Binary, Complete System</h2>
            <p class="text-body leading-relaxed mb-4">
                A Congo application compiles to one file. That file contains your business logic, your HTML templates,
                your static assets, your database driver, and your migration logic. Deployment is
                <code class="text-accent">scp</code> and <code class="text-accent">./app</code>. Or use
                <code class="text-accent"><a href="/guide" class="text-accent hover:text-bright transition-colors" hx-boost="true">congo launch</a></code> to handle Docker and infrastructure automatically.
            </p>
            <p class="text-body leading-relaxed mb-4">
                No runtime to install. No package manager. No node_modules. No virtualenv.
                Go compiles everything into a static binary that runs on any Linux server. Your deployment target
                needs nothing installed except an operating system.
            </p>
            <div class="quote-bar">
                <p>Your entire application is one file. Copy it to a server and run it. That's deployment. That's the whole ops story.</p>
            </div>
        </section>

        <!-- Summary -->
        <section class="section-divide py-16">
            <p class="text-body leading-relaxed">
                These choices share a common thread: reduce moving parts, own your stack, and build things that last.
                Congo isn't trying to be the most popular framework. It's trying to be the one you never have to migrate away from.
            </p>
        </section>

    </div>

    <div class="text-center">
        <a href="/guide" class="btn-glow btn-glow-primary" hx-boost="true">Start building</a>
    </div>

    <div class="mt-16 max-w-md mx-auto">
        {{template "mailing-list.html" .}}
    </div>
</div>
{{end}}