Launching an empty community site without faking it
Passion, 28 April 2026
A community platform with nothing in it does not look new, it looks broken. Empty grids read as bugs, the layout collapses without content in it, and the first genuine visitor sees a site that nobody is using and concludes, correctly, that nobody is using it. So you seed it with plausible examples before launch. Everyone does. Then eighteen months later your own statistics page is quoting a fixture file back at you and you cannot tell your first real user from row 47 of a migration.
We know because we did it, and this piece is mostly an account of what it cost.
What our own numbers say
One of our platforms is a set of tools for collective action: petitions, unions, referendums, boycotts, mutual aid networks, citizen journalism. Before launch it was populated with a comprehensive set of example campaigns for its initial region, written into a seed migration alongside the schema.
The headline figures on the site come from that migration: 548,194 signatures, and a raised total in the tens of millions. The live statistics endpoint, which counts rows created by real accounts, returns eight users, eight comments, two likes and fifteen shares. Both sets of numbers are on the same website, generated by the same codebase, and only one of them describes anything that happened.
The identifiers give it away to anyone who looks. The petitions on the live site carry the prefix from the seed file that created them. Nobody should quote the large figures as adoption, and that includes us, which is why the portfolio entry for the project says so in plain words.
Why seeding is so tempting
The reasons are all real ones. Empty states look unfinished to reviewers and investors. Screenshots need content. Layouts that were designed around cards need cards. Pagination and filtering cannot be tested against three rows. Search returns nothing and you cannot tell whether that is correct.
Every one of those needs is satisfied by a seeded development database. Not one of them requires the production one. The step that causes the damage is not writing the fixtures, it is running them against the live site and then leaving them there.
The four costs
You lose your instruments. The point of an early platform is learning what real people do with it. If the database is ninety-five percent fixtures, your analytics are measuring your own imagination. Your first genuine signature arrives and nothing on any dashboard moves, because it is one row among hundreds of pretend ones.
Fake content behaves nothing like real content. Seeded posts are well-formed, moderately long, correctly spelled and free of abuse. Real submissions include a four thousand word rant, emoji in the title, a URL where the description should be, three duplicate posts from someone who thought the button was broken, and something you have to remove within the hour. Search ranking, moderation rules and layout limits tuned against fixtures are tuned against a fantasy, and every one of them fails on contact.
It leaks. Sequential identifiers, prefixed slugs, timestamps clustered in the same hour, every campaign with exactly one comment, avatars from the same stock set. Anyone technically curious works it out in about a minute, and having worked it out they now discount everything else the site tells them.
It is a factual claim you did not mean to make. This is the serious one. A signature count on a petition site is not decoration, it is the entire proposition. Saying half a million people signed something is a statement about the world. Design copy can be aspirational; a counter cannot.
If you must seed, keep the two apart in the schema
Make it a column, not a convention, and make the reporting path unable to ignore it.
ALTER TABLE petitions ADD COLUMN is_seed INTEGER NOT NULL DEFAULT 0;
ALTER TABLE users ADD COLUMN is_seed INTEGER NOT NULL DEFAULT 0;
-- anything a visitor reads as a fact must exclude fixtures
SELECT COUNT(*) AS signatures
FROM signatures s
JOIN petitions p ON p.id = s.petition_id
WHERE p.is_seed = 0;
-- and removing the lot is one statement, not an archaeology project
DELETE FROM petitions WHERE is_seed = 1;
Two rules follow from that column. Public counters and statistics endpoints filter on it, always, with no exceptions for the homepage. And seeded records are labelled in the interface as examples. An example that says it is an example does all the layout work you wanted and makes no claim at all, which turns out to be the whole trick.
How to launch empty and still look alive
Design the empty state first and treat it as the main screen, because for the first month it is. The primary action on an empty listing is create, not browse. Most products get this backwards and bolt a grey illustration onto a page built for a full grid.
Show the shape instead of instances. A short, clearly marked example of what a petition on this site looks like teaches a visitor more than twenty fabricated ones, and costs you no credibility.
Launch narrow. One real campaign run by one real group beats twenty invented ones. Three genuine items with visible dates on them read as new. Two hundred items with no activity since March read as abandoned, which is a worse impression than emptiness by a distance.
Show recency rather than volume. "Started four hours ago" on a handful of items signals life. A large total that has not moved in six months signals the opposite, and a volume counter on a new site is a hostage you have handed over voluntarily.
Do not render a statistic that has nothing to say. A wall of twelve zeros is bleak and it is the honest option, so avoid the choice: leave the tile out until the number is worth showing.
Give a lone visitor something to do that does not need other people. Drafting and saving something, following a tag, subscribing to a topic. A person who leaves having made one thing might come back. A person who leaves having read an empty grid will not.
The pattern done right, in the same codebase
The crowdfunding section of that same platform records a pledge and nothing more. There is no payment integration in it, and rather than displaying a total that implies money moved, the page tells the user directly that payments are not connected yet.
That is exactly the right instinct, sitting a few directories away from the seeded counters that are exactly the wrong one. The difference between the two is not skill or effort. It is whether anyone asked, at the moment the number went on the screen, what a stranger would reasonably believe after reading it.
Being empty is a condition that fixes itself. Being caught inflating is not, and the repair costs far more than the empty grid ever would have.
The platform, its real numbers and its state: Jonosakti.