Supabase
The first commit of Supabase is not a database. It's a Next.js marketing website for a product that did not yet exist, advertising features that never shipped.
1a374516deSupabase is a backend platform built around PostgreSQL. It provides authentication, file storage, row-level security, realtime database subscriptions, edge functions, and a dashboard to run SQL against your data. Its tagline today is "the open source Firebase alternative," and its current valuation is measured in billions.
Here is what was in its first commit.
1. Not a database
Zero lines of PostgreSQL. Zero lines of Go, Rust, or Elixir. No auth service. No storage service. No realtime code. No SDK. No CREATE EXTENSION. No reference to Firebase anywhere.
Instead, 26 files and 17,639 lines, most of which are in yarn.lock, implementing a Next.js marketing website with a Bulma CSS theme, a MobX store, a docs/ sub-package built on docz, an SVG logo, and a 298-line SCSS stylesheet.
There is one file in the commit called packages/web/pages/index.js. It is 117 lines of JSX. It describes, as if it already existed, a product called Supabase that can supercharge your database. The product did not exist. Paul Copplestone, Supabase's future CEO, was alone at his keyboard, committing the sales copy before the code.
This is a new kind of initial commit and I think it deserves a name. Next.js's first commit was a spec for a framework that did not exist. Homebrew's first commit was a manifesto for a package manager that did not exist. Supabase goes one further: it is a landing page for a product that did not exist. The README, the Navbar, the homepage, the pricing section, even the "COMING SOON" tags: all of it describes a real product, present tense, confident, ready to buy. There is just no product to buy yet.
2. "Supercharge your database"
The original Supabase positioning is different from today's. The README.md is 16 lines long, and its entire description of the project is three words:
"Supercharge your database."
Not "Firebase alternative." Not "open source." Not "Postgres." The word "Postgres" does not appear in the README at all.
On the homepage, pages/index.js, the tagline is slightly different:
"Supercharge Postgres without a single line of code."
Already in the first commit, there is a slight tension between the two framings. Is Supabase about any database, or specifically about Postgres? The README says any database. The homepage says Postgres. The homepage was right. Everything Supabase would go on to build is Postgres-specific, because Postgres is the database with the richest extension ecosystem and the strongest open-source story. But on day one, the README and the homepage disagree by 50% about what the product even is.
The phrase "without a single line of code" also makes a cameo in six different places in the commit. Supabase was, originally, pitching itself as a no-code layer on top of Postgres. You would not write SQL. You would point Supabase at your database, and it would expose your tables as APIs. The no-code framing got quietly walked back over the years as the audience turned out to be developers who very much wanted to write SQL and appreciated Postgres being out in the open.
3. The plugin store that never happened
Here is the weirdest thing in the first commit. If you open packages/web/components/Navbar.js, you will find a dropdown menu labeled "Plugins" with two items:
PostGIS: Supercharge your database to work with locations and geographies.
Timescale: Supercharge your database to work with time series data.
PostGIS and TimescaleDB are real Postgres extensions. The original Supabase vision was to be a marketplace for Postgres extensions. You would come to Supabase, you would pick your plugins, and Supabase would spin up a Postgres instance with those extensions preinstalled and present them to you as clean SaaS features. PostGIS would become "Locations." Timescale would become "Time Series." The pitch was Postgres extensions, but friendly.
This is not what Supabase became. Supabase became an integrated backend platform with a fixed set of capabilities (Auth, Storage, Realtime, Database, Edge Functions) rather than a pick-your-own-extensions marketplace. The "plugin store" vision is still visible in the first commit as a ghost: there is a packages/web/pages/plugin/[slug].js file, 170 lines long, implementing a dynamic route for plugin detail pages. At 170 lines it is the single longest source file in the whole commit. Supabase spent more thought on the plugin-detail page layout than on the homepage layout.
/plugin/[slug] is a route that never shipped into the product Supabase actually became. It exists only in this first commit and in the handful of commits after it.
4. The product list that didn't survive contact with reality
Scroll further into pages/index.js and you find a grid of six "Apps" that Supabase is going to offer. Here they are, in order, with their original taglines:
- Realtime: "Subscribe to all changes to your database over websockets."
- Restful API: "Add a fully documented Restful API, without a line of code."
- GraphQL: "Add a fully documented GraphQL API, without a line of code."
- Admin API: "Manage your database with a Restful API rather than SQL."
- Forms: "Embeddable and customizable forms, fully validated and secure. COMING SOON"
- Dashboard: "Manage your database with a Restful API rather than SQL. COMING SOON"
Let me walk through what happened to each of these, because the ratio of shipped-to-unshipped is the whole story of Supabase's first year.
- Realtime: shipped. Built on Elixir and Phoenix. Became one of Supabase's signature features. Exactly what the day-one description promised: websocket subscriptions to Postgres changes.
- Restful API: shipped. Supabase wraps PostgREST, an open-source tool that generates a REST API from a Postgres schema. Someone else had already solved the problem; Supabase bundled it.
- GraphQL: shipped, eventually. Took much longer. Today it is powered by pg_graphql, an extension Supabase developed themselves.
- Admin API: shipped. Became the Supabase management API.
- Forms: never shipped. Supabase, in its first commit, was going to compete with Typeform. They planned to let you build forms that wrote directly into your Postgres tables. The feature is tagged "COMING SOON" on the homepage. It never came. It was quietly removed from the roadmap within the first year, as the team realized they had their hands full with the database-facing primitives and did not need to pick a fight with SaaS form builders.
- Dashboard: shipped. Became studio.supabase.com. Funny detail: the original description of "Dashboard" in the first commit is identical to the description of "Admin API"; both say "Manage your database with a Restful API rather than SQL." It is clearly a copy-paste in progress. Paul was moving fast.
Now look at what is missing from that list of six. Supabase today has two features that are not on it:
- Auth. The thing that most Supabase users actually come for: the drop-in auth service with social login, email/password, JWT, row-level security integration. Not in the day-one vision. Auth was added later.
- Storage. S3-compatible object storage with Postgres-based access control. Also not in the day-one vision. Also added later.
Auth and Storage are arguably the two most important Supabase features today. They did not exist in the founder's imagination when he committed the landing page. The product found them along the way.
This is a pattern I keep seeing in these initial commits. The things the founders planned for tend to get walked back. The things that made the product great tend to be things they hadn't thought of yet. The first commit is not a map of the territory. It is a guess at what the territory is going to contain, and the interesting question is how wrong the guess was.
5. Built on Next.js
There is one more detail in this commit that I cannot resist pointing out, because it closes a loop with the very first issue of this newsletter.
Supabase's first commit is built with Next.js.
You can see it in packages/web/next.config.js, in packages/web/pages/, in the _app.js and _document.js convention. Supabase used the file-system-based routing convention that Guillermo Rauch described in the Readme.md of the Next.js repository on October 5, 2016. Three years, almost to the day, before Paul Copplestone committed this file.
Supabase's landing page is built on top of the framework that Issue #1 of this newsletter was about. The first commit of Next.js, three years later, had produced a framework mature enough to become the foundation for the first commit of Supabase. Next.js Issue #1 is the cause of the feasibility of Supabase Issue #12. There is nothing profound about this. Next.js was becoming the default React meta-framework at exactly the time Paul Copplestone was starting his startup. But I find it quietly beautiful anyway. The repos rhyme.
And of course: by the time you read this, the website at supabase.com is still built on Next.js. It has been rewritten many times, but the framework has stayed the same. The file-system is still the API.
6. "Init monorepo"
The commit message is "Init monorepo." Not "initial commit," not "first commit," not "Supercharge your database," not "hello Supabase." Paul Copplestone's first public act as Supabase's founder was to create a yarn workspaces monorepo with two packages (web and docs) and to tell git about the structure.
Think about that for a moment. There is one person. There is no product. There is no team. There are no users. There is no code for the actual thing the company is going to build. There is just a marketing site and a placeholder docs site.
And the first thing Paul does is set up a monorepo.
On one level, this is massively premature. Monorepos are tools for managing complexity across multiple packages. When you have two packages and one of them contains a single file called hello.mdx, a monorepo is overkill by several orders of magnitude.
On another level, this is absolutely correct. Paul knew that Supabase was going to be many things: a database layer, an auth service, a storage service, a realtime service, a dashboard, client libraries in multiple languages. And he knew that all of these things were going to share a repository. Setting up the monorepo infrastructure on day one, before any of those things existed, meant that none of them would need to be migrated later. The machinery would already be there.
This is, I think, the opposite lesson from the one I took from Node's first commit. Node's first commit said nothing begins from nothing; Supabase's first commit says you can set up the machinery for an ambitious project before the ambitious project exists. Both are true. Paul did not have Auth or Storage or Realtime on day one. He did not even have a database connection. But he had a monorepo, and because he had a monorepo, the packages that would later exist had a place to live.
The Supabase monorepo today contains many dozens of packages. The root package.json in this first commit, 23 lines, is the seed. Paul started by planting the tree.
7. Footnotes from the commit log
- Supabase was founded by Paul Copplestone and Ant Wilson. Ant is the CTO; Paul is the CEO and the person who typed this commit. Ant's first commit to the repository comes a few days later.
- Supabase went through Y Combinator in the summer 2020 batch, about eight months after this commit. In those eight months, the marketing site Paul committed here was replaced by a working product and a landing page that actually described what Supabase could do.
- The original Supabase logo, in this commit as
packages/web/public/supabase-logo.svg, is 16 lines of SVG and is not the logo Supabase uses today. The current green lightning-bolt mark was introduced later. - The docs sub-package uses docz, a MDX-based documentation tool that was popular around 2019 and has since been largely abandoned. Supabase's current documentation is, of course, built on Next.js, using a custom setup that evolved from the one in this commit.