Bespoke is shutting down. We pivoted!
Tags: webdev, remix, nestjs
Published: 2023-07-24 15:33:01

Please note: This article has not been parsed through ChatGPT. I wrote it with individual keystrokes.



## Why we pivoted [Bespoke](https://github.com/bespoke-surf/bespoke/)

19 days ago from July 24th, we open sourced Bespoke. Launched it on [HN](https://news.ycombinator.com/item?id=36586490). We have been building Bespoke for the past eight months.

We intended to create a Personalised Marketing Platform which contained the best parts of Mailchimp, Substack, Klaviyo and Typeform.

We reached around 228 Github stars, whilst we were building Bespoke every day, we changed our marketing speak from the Open Source Mailchimp alternative to  "Capture, Engage and Target" customers.

As the marketing speak evolved, this resonated with a lot of users and SaaS operators. Thus based on the market feedback. We completely Pivoted!

We will launch our pivoted product soon. Most of the codebase is around 80% reusable.

## A little bit about Bespoke's architecture and what we learned.

The stack contained:

- Remix
- NestJS
- Monorepo with Turbo and Yarn

The architecture that we followed was BFF (Backend for frontend) architecture

The biggest mistake that we made was using a cookie-based authentication directly from our 2nd backend layer. As our product evolved, we understood this could have been better, and a dual authetication layer is presumably the best. Should have read this [article](https://dev.to/damikun/web-app-security-understanding-the-meaning-of-the-bff-pattern-i85) all along.

Also, we were implementing simple CRUD in the beginning, and as the product evolved, things started getting complicated with events, listeners, queues etc. Should have started with a CQRS-based system.

Also in the UI layer, as the user signed up with a business name, we would always use the business name as the subdomain. Our flow would redirect to the users' app page from our landing page if they are logged in. This would query the database on each load, even if an anonymous user visited our landing page. Occasionally if the back end was updating, the front end would hang. This was a pain. 

Note: This can be solved by changing the user flow, and not redirecting.

Also, we needed to keep tabs on the subdomain reserved list if we created any business-centric subdomains for our main website.


## The tech that we choose right

- Remix with flat-routes
- The BFF architecture was great for product velocity. 
- Using Nestjs rather than implementing the back end entirely in Remix
- Using a monorepo
- JSONB in Postgres is very reliable and based on different data that we saved to the database, especially Shopify data. It was fast and easy to query.
- GraphQL, TypeORM with TypeGraphQL code-first approach.
This made writing TypeGraphQL types, entities and type assertions very interlinked with each other. Velocity was fast was because of this.

Another thing to note about querying the database here is using TypeORM. Creating relation entities, where clause [bracket](https://github.com/typeorm/typeorm/blob/master/docs/select-query-builder.md#adding-where-expression:~:text=You%20can%20add%20a%20complex%20WHERE%20expression%20into%20an%20existing%20WHERE%20using%20Brackets) assertions, and subqueries are very easily done with TypeORM. Love using it.

In the pivoted product that we hopefully will release ASAP, we did think about choosing Sqlite with LiteFS, but just because of the reliability of JSONB, and probably we might need to query a JSON string in the future. We are reverting to choose Postgres again. CockroachDB looks promising here.

Give us best wishes and a smile, hopefully, we will launch the pivoted product soon. A wait list will be launched in a week presumably.

Thank you for reading
Afi

[Twitter](https://twitter.com/zifahm1)
[Threads](https://www.threads.net/@afiiiiiiiiiiiiiiiiiiiiiiiiiii)