Solobase - The Single-Binary Backend Solution

Inspiration

As a developer, I was tired of the same recurring pattern: every new project meant reimplementing authentication, user management, file storage, and all the other backend basics from scratch. I wanted a vendor-free, open-source backend that would let me focus on building my actual application instead of reinventing the wheel.

I tried existing open-source alternatives, but they all had significant drawbacks. Some required complex Docker orchestration with multiple containers, a endless amount of environment variables, or hours of configuration/debugging just to get started and working. Others were so restrictive in their architecture that customizing them for specific needs felt like fighting against the framework rather than working with it. Many claimed to be "open source" but pushed you toward their cloud services or had critical features locked behind paid tiers, or could not be extended.

I wanted something simple: a backend that was genuinely free from vendor lock-in, simple enough to run on a $5 VPS, yet powerful enough to be able to scale to production. No hidden costs, no forced cloud dependencies, no artificial limitations - just a solid foundation that respects developer freedom and gets out of your way.

The hackathon and Kiro provided the perfect opportunity to build this vision: a single Go binary that includes everything you need, works out of the box, and can be extended however you want. True simplicity without sacrificing capability.

What it does

Solobase is a comprehensive, backend that provides everything you need to build modern web applications in a single binary built from go:

Core Features

  • πŸ” Authentication & Authorization: Complete auth system with JWT tokens, user management, password recovery, and role-based access control (RBAC) powered by Casbin
  • πŸ’Ύ Multi-Database Support: Seamlessly works with SQLite (default) and PostgreSQL through GORM ORM
  • πŸ“ File Storage: Dual-mode storage supporting both local filesystem and S3-compatible cloud storage with quota management and secure URL generation
  • 🎨 Admin Interface: Beautiful Svelte-based UI for managing users, database collections, system settings, and monitoring application health
  • πŸ”Œ Extension System: Compile-time plugin architecture allowing developers to extend functionality with custom modules while maintaining security through schema isolation
  • πŸ“Š API Management: RESTful APIs with automatic OpenAPI documentation, request logging, and comprehensive middleware support
  • πŸ“ˆ Monitoring & Observability: Built-in Prometheus metrics, structured logging, request tracing, and health checks

Developer Experience

  • Zero Configuration: Works out of the box with sensible defaults
  • Single Binary Deployment: One file to rule them all - no dependencies required
  • Multi-tenant Support: Application ID isolation for running multiple apps on the same instance
  • Hot-reload Configuration: Update settings without restarting the server
  • TypeScript SDK Generation: Automatic client library generation for type-safe frontend development

How I built it

Technical Architecture

The project leverages Go's powerful compilation model to bundle everything into a single executable:

Solobase Binary
β”œβ”€β”€ Go Backend (Embedded)
β”œβ”€β”€ Svelte UI (Embedded)
β”œβ”€β”€ Core Services Layer
β”‚   β”œβ”€β”€ Auth -> User management & JWT
β”‚   β”œβ”€β”€ DB -> Multi-database support
β”‚   β”œβ”€β”€ Storage -> Local & S3 files
β”‚   β”œβ”€β”€ IAM -> RBAC with Casbin
β”‚   └── Logs -> Metrics & events
└── Extension System
    β”œβ”€β”€ Webhooks -> Event notifications
    β”œβ”€β”€ Analytics -> Usage tracking
    └── Custom -> Your extensions

Technology Stack

Backend (Go 1.23):

  • gorilla/mux for routing with middleware chains
  • GORM for database abstraction and migrations
  • golang-jwt for secure token generation
  • Authboss for authentication
  • Casbin for flexible RBAC authorization
  • Prometheus client for metrics collection
  • embed package for bundling UI assets

Frontend (Svelte/TypeScript):

  • SvelteKit with static adapter for SPA generation
  • Skeleton UI for component library
  • TailwindCSS for styling
  • Chart.js for data visualization

Challenges I ran into

1. The Complete Technology Pivot

The biggest challenge was completely changing direction mid-project. I originally spent weeks building Solobase using Deno and Fresh (https://github.com/suppers-ai/builder), believing in the promise of modern JavaScript runtime. However, I kept hitting fundamental restrictions:

  • Deployment limitations - couldn't deploy everywhere I wanted
  • Runtime dependencies - always needed Deno installed
  • Binary compilation issues - couldn't achieve the single-file distribution I envisioned
  • Performance overhead from the JavaScript runtime

After weeks of work, I made the hardest decision: throw it all away and rebuild in Go. It was painful to discard so much effort, but I knew it was necessary to achieve my vision of a single binary with no runtime dependencies that was truly fast. This decision taught me that sometimes the courage to start over is more valuable than the sunk cost of continuing down the wrong path.

2. Scaling from Hobby to Production

Designing a system that works elegantly for both a weekend side project and a production application with millions of users was incredibly challenging. I needed:

  • Local filesystem and SQLite for simple deployments (perfect for that $5 VPS)
  • PostgreSQL and S3 storage for production scale
  • Seamless transition between configurations without code changes

Solution: GORM's database abstraction made this possible, allowing the same code to work with different databases. The storage layer abstracts filesystem vs S3, letting users choose based on their needs, not our limitations.

3. Dynamic Extension Architecture

Creating truly dynamic extensions without sacrificing the single-binary approach was a complex design challenge. I spent countless hours bouncing ideas off Kiro's planning tools, iterating through different approaches:

  • How to allow custom functionality without runtime plugin loading?
  • How to maintain security while giving extensions database access?
  • How to make extensions powerful yet simple to create?

The breakthrough came with compile-time extensions with runtime configuration. Extensions are compiled in, but their behavior can be dynamically configured.

4. Building Truly Flexible Systems

One of my proudest challenges was creating the products extension with a formula-based pricing system. Instead of hardcoding pricing models, I built a system where you can define any mathematical formula for pricing, for example:

  • Simple pricing: base_price * number_of_items
  • Sell by usage: base_price + (usage * rate)
  • Complex subscriptions: monthly_base + max(0, users - included_users) * per_user_rate

This allows selling literally anything with any pricing model you can express mathematically - from simple single priced products to complex products that require complex pricing structures - all without changing code.

Kiro's tools were invaluable here, serving as a sounding board for ideas and helping validate architectural decisions before committing to them.

Accomplishments that I'm proud of

The main accomplishments have been overcoming the challenges mentioned above, but in short they have been:

  1. Creating a full-featured backend with both frontend and backend all in a single ~50MB binary file that can be run anywhere - no Docker, no Node.js, no runtime dependencies whatsoever

  2. Making the brave decision to pivot from Deno/Fresh to Go after weeks of work, proving that sometimes starting over is the right choice even when it's painful

  3. Achieving true scalability flexibility where the same binary works perfectly for a hobby project on SQLite and local storage, or a production deployment with PostgreSQL and S3, without any code changes

  4. Building a genuinely extensible system through the compile-time extension architecture that maintains security while allowing unlimited customization

  5. Creating innovative solutions like the formula-based pricing system that can handle any mathematical pricing model, making it possible to sell anything from simple products to complex SaaS subscriptions

  6. Delivering on the original vision of a vendor-free, truly open-source backend that respects developer freedom and just works out of the box in seconds

What I learned

  1. Sometimes starting over is the right choice: The painful decision to abandon weeks of Deno/Fresh work and rebuild in Go taught me that sunk cost fallacy can kill a project. Having the courage to pivot was more valuable than the time already invested.

  2. Go is perfect for this use case: Go's compilation model, embed package, and performance characteristics made it ideal for creating a single-binary distribution. What seemed impossible in JavaScript became straightforward in Go.

  3. Simplicity is the ultimate sophistication: Making something simple to use (one binary, zero config) requires significant complexity under the hood. The easier it is for users, the harder it was to build.

  4. Flexibility doesn't mean complexity: By using abstractions like GORM and interface-driven design, I could support multiple databases and storage backends without complicating the user experience.

What's next for Solobase

My immediate focus is on three key areas:

  1. Building real applications with Solobase: I want to dogfood my own creation by building production applications that use Solobase as their backend. This will help identify pain points and missing features from a real user's perspective.

  2. Making it production-ready: Most of the code was vibe coded, I'll be focusing on hardening the codebase, improving error handling, and ensuring it can handle production workloads reliably.

  3. Engaging with the community: The most important next step is to engage with developers using Solobase to understand their use cases and the features they need. Community feedback will drive the roadmap - whether that's better documentation, specific integrations, new extensions, or core improvements.

Built With

Share this project:

Updates