Speeding up Strapi development times

Divakar Rajesh
4 min readDec 23, 2023

I’ve used strapi in couple of my exploratory projects. Be it AI or that project which I dearly hope will make me millions in the near future.

I’ve started using Typescript because whenever I type something, it would give me autocomplete or “Intellisense” in VSCode, so that i don’t have to remember those methods and even help explore new ones that I don’t know yet.

But the problem with Typescript is that there is a compilation step involved that needs to happen before your browser or Node.js environments can run them. Projects like create-react-app, Vite starter templates, Next.js starter template would give this to you, out of the box. Strapi did support it too. But it was just slowwwwer. My first thought was,

“Should I stop using TypeScript?”

Every time i change a file, it takes me solid 16s+ for the server to restart on an M1 Pro in a MacBook Pro 14 inch.

Apple boasting their chip is the fastest in the market. Meanwhile me noticing that it still takes 16s+ to compile a bunch of .ts files?

The Compiler

May be it wasn’t my laptop that’s slow(obviously!). I’ve seen create-react-app bootstrapping the whole app in 4–5s. Whenever I change a file and hit save, the changes are already on the site.

One thing I noticed about Strapi, is that they seem to compile the TypeScript files to a directory and run the JS code from there. So my first suspect was obviously just that, the TypeScript compilation step. By default, it is tsc that is compiling. I just swapped it out, with the more faster swc and the results were clear! For this to work, you need to install the following

npm i -D @swc/cli @swc/core

I didn’t dare to replace the compilation in the “PRODUCTION” Node.js environment, so bear with me on this. Just replace the node_modules/@strapi/typescript-utils/lib/compile.js with this

'use strict';

const compilers = require('./compilers');
const { exec, execSync } = require('child_process');

const getConfigPath = require('./utils/get-config-path');

module.exports = async (srcDir, { configOptions = {} } = {}) => {
if (process.env.NODE_ENV === "development") {
let msg = "SWC Typescript compilation"
console.log(srcDir)
console.time(msg)
await Promise.all(
[
exec("npx swc server.ts -d dist --config-file .swcrc"),
exec("npx swc config/ -d dist/config --config-file .swcrc --copy-files"),
exec("npx swc build/ -d dist/build --config-file .swcrc --copy-files"),
exec("npx swc src/ -d dist/src --config-file .swcrc --copy-files"),
]
)
console.timeEnd(msg)
}else{
let msg = "Typescript compilation"
console.time(msg)
const configPath = getConfigPath(srcDir);
console.log(configPath, configOptions)
compilers.basic.run(configPath, configOptions);
console.timeEnd(msg)
}
};

and create a .swcrcin the root of the project with this.

{
"$schema": "https://json.schemastore.org/swcrc",
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"target": "es2018"
},
"module": {
"type": "commonjs"
},
"sourceMaps": true
}

Essentially, we’re just asking it to use swc during development. We need the SourceMaps, so that we can debug our app by putting breakpoints and VSCode would know which Typescript code to point back to. And the results are here:

Woot Woot!

That’s a solid 12s saved every time you hit save on your IDE.

So now you can focus on making more apps that brings in revenue rather than waiting for your compiler to compile your code 🙌🏻

Hey👋 — I’m Divakar Rajesh, a Product Engineer at Sensara — You’ve probably interacted with our products if you have tried Xiaomi Mi Remote, or used the search experience on Zee5 (the list goes on and on..) as we’ve made our mark in the OTT and Linear TV & media space.

On a personal note😛, you can find me on Twitter and other socials as @sdivakarrajesh — Shameless plug 🤦‍♂️ — See ya..

--

--