What 62,000 sign-ups and 346 paying users taught me about Codewell
I co-founded a practice platform for new frontend developers in 2021, built every line of it, and closed the paid plan in 2023. The numbers, the stack, and what I would do differently.
- 62,000GitHub sign-ups
- 346paying users
- 1 in 140ever paid
- 2 yrsthe paid plan ran
In March 2021 a designer partner and I started Codewell: a site where new frontend developers practise on real design templates instead of to-do apps. You pick a design, build it in HTML and CSS, post your solution, and compare it with everyone else's. Sixteen templates were free, nine were behind a paid plan.
I wrote all the code. My partner did the designs, the templates and the community. We launched on 9 May 2021 and closed the paid plan in July 2023. Here is what the records say, now that I have gone back and read them.
The numbers
- 23,500 people signed up with GitHub in the first year. 62,000 by March 2024, when I took the last backup.
- 346 of them paid: 308 on the monthly plan at $8, 38 on the yearly at $72. At the peak, in spring 2022, about 70 subscriptions were active at the same time.
- 25 challenges: 16 free, 9 premium.
- 1,466 solutions posted by 888 different people, and 245 comments on them.
- An 8,400-reader newsletter, which I ran on Substack and later EmailOctopus.
- Search sent 56,000 clicks in the last 16 months the site was up, most of them from India and Brazil. The paying users were mostly in the US.
So the top of the funnel was big and the paid conversion was thin: about one in 140 of the people who signed up while the paid plan existed ever paid. That ratio, more than anything else, is the story.
The stack
The first version was Create React App on Netlify, talking to a Strapi API on Node.js and MongoDB through GraphQL, with uploads to S3 and GitHub login. In August 2021 I moved the frontend to Next.js for server rendering and ran it on AWS Lambda@Edge, CloudFront and S3 with the Serverless Framework. The API started on Heroku and moved to Elastic Beanstalk before launch. Sentry caught the errors, Ant Design gave me the components, everything was TypeScript.
Billing ran through FastSpring, because Stripe was not available in my country then. A webhook handled activation and deactivation, and cancellation went through the FastSpring API. There was no handling for failed payments. I only noticed that this week, reading the code again.
In spring 2023 I started a rewrite as a Turborepo with Next.js 13, tRPC, Prisma on Postgres and NextAuth. It got as far as login, the challenge list and the editor, and then stopped after four weeks. The paid plan closed three months later.
What I would do differently
Charge for the thing people came for. People came for the templates, and 888 of them posted solutions. The paid plan gated the Figma files and the premium templates, which is reasonable, but most never needed more than the 16 free ones. A smaller free tier and a yearly-only paid plan would have converted better than $8 a month against free.
Write the webhook for the unhappy path first. Activation and cancellation are the easy events. Failed renewals are where the money leaks, and I never handled them.
Do not start a rewrite when the business is slowing. The 2023 rewrite was an engineer's answer to a product problem. Four weeks of tRPC and Prisma did nothing for conversion.
Keep the data. The only reason I can write this post is a mongodump from March 2024. Most of the numbers above came out of it in an afternoon; the search figures came from a Search Console export.
What it gave me
Two years of running a paid product end to end: the frontend, the API, the deployment, the billing, the analytics, the support emails. That is the experience I now use on Heard and Blip, where every webhook verifies its signature and a failed renewal keeps the plan through Stripe's retries, then ends it.