← Articles

Dec 6, 2021◆4 min read

Why I chose Strapi for a crypto dashboard

A 2021 backend decision: public market data, private portfolios, and the cost of keeping control of the stack.

Originally published December 6, 2021. Edited for clarity and illustrated in September 2026. This account describes the choices I made in 2021, not the current capabilities of these products.

In 2021 I was building a dashboard for tracking cryptocurrency. It had two kinds of data. Currency prices were public: anyone visiting the site could see the live widgets on the homepage. Portfolios were private: a signed-in user saw their own transactions alongside those prices, and nobody else's.

The frontend was already settled. I had it in Vue and Nuxt and was happy with it. What I needed was a backend I could get running quickly and wouldn't regret: somewhere to define the data, an API to reach it, and rules about who could see what.

What I needed from the backend

My list was short but specific:

  • Custom data models with relationships. A user has many transactions; a transaction refers to an asset. I wanted to design that structure, not bend it to fit a blogging schema.
  • API access. REST at minimum, GraphQL if it came cheaply, so the Nuxt frontend could request exactly what each view needed.
  • Authentication and authorization. Public endpoints for market data, and private records that only their owner could read. I also wanted multi-factor authentication to be possible.
  • Hosting I could move. I didn't want the data model tied to one cloud provider's proprietary services.

Those were requirements. What I actually shipped is a separate question, and I keep it separate below.

Swipe diagram to explore →

A Nuxt interface requests data through a Strapi API, with separate public market data and access-checked private portfolio records.
The dashboard's logical data boundary: public information and private records must not share the same access rules.

Why the first options fell short

I started with what I knew. I'd built on WordPress for years and there were affordable plugins that approximated a members' area. In the setups I tried, though, a user's private area amounted to a single page or view, responses felt slow for a live dashboard, and adding custom client-side behavior meant working around the theme rather than with it. That's a verdict on the particular plugins I looked at for this job, not on WordPress as a whole.

After more research I narrowed it to two candidates: AWS Amplify and Strapi.

Amplify was a set of tools for configuring and deploying AWS services (data modeling, an API layer, authentication) from one interface. Strapi was an open-source, self-hosted headless CMS built on Node and React. It gave me an admin UI for designing content types and their relationships, exposed them as REST or GraphQL endpoints, and could run on PostgreSQL.

Why I chose Strapi

The deciding moment was practical. When I tested Amplify in May 2021, its data-modeling UI didn't behave as I expected: once the database services were deployed, the UI I'd used to define the models couldn't access or modify them. That was one test at one point in the product's development, not a verdict on Amplify. But it meant the part of Amplify I most wanted was the part I couldn't rely on.

With Strapi, the models were things I could see: content types in the admin, files in a code folder I could put under Git. If I needed behavior the UI didn't provide, I could extend its controllers and services with ordinary Node code. And because I hosted it myself, the data lived on a server I chose.

What I had to operate

Self-hosting is a trade. Amplify would have run much of the infrastructure for me; with Strapi I ran it.

DigitalOcean offered a Strapi server image that made the first deployment quick. It bundled Nginx as a reverse proxy, the Strapi application on Node.js, a PostgreSQL database and PM2 to keep the Node process running. I still had to set up TLS certificates for Nginx myself. After that came the ongoing list: operating system and dependency updates, Strapi upgrades that sometimes required changes to my custom code, backups, and watching the running application. I also added an external monitoring and security service for the Node runtime.

Swipe diagram to explore →

Browser requests pass through Nginx to Strapi and PostgreSQL, with PM2 managing the application process inside a self-operated infrastructure boundary.
A simplified reconstruction of the self-hosted stack described in the 2021 account; operating responsibilities stay with the owner.

It helps to keep two layers apart here. Strapi's users-and-permissions system decided whether a signed-in user could read a given record. That is application authorization. Keeping PostgreSQL patched, backed up and unreachable from the public internet is a different job, and Strapi doesn't do it for you.

Strapi documented email-provider integrations for registration and verification, and plugin support for AWS Cognito, which offered SMS phone verification as a second factor. Having that option was part of why it fit my requirements. The option being available is not the same as it being deployed, and I'm not claiming more than that here.

The original version of this article said both PostgreSQL and Node could scale horizontally behind a load balancer. That was too simple. Application instances can be scaled out that way. A relational database can't: adding capacity means dealing with replication, connection limits and where writes go.

What the choice bought me

I got a data model I designed and could read, an API shaped to the frontend, and hosting I could move without rebuilding the application.

What I gave up was having someone else operate it. Every certificate renewal, upgrade and backup was mine. For a small project where owning the model and the data mattered more than saving those hours, that was the right side of the trade. The operating list was the price of that control, and it's worth writing down before choosing, not after.