Using typescript to make an express app, only compiled javascript file is being hosted

Hello,

I’m learning how to host web applications on Vercel and I’ve been trying to make a template project using Express and Typescript as a beginning foundation. I’ve placed all of my code inside of a src folder, with an api directory containing the server entry point index.ts. I’m using tsup to compile my typescript code into javascript code in the dist folder.

For my project settings on Vercel, I have the “Install Command” set to npm install --include=dev (since I need typescript and tsup to build), the “Build Command” set to npm run build, and the “Output Directory” set to ./dist. No “Development Command” and no “Root Directory” overrides.

For my vercel.json file, I have a “rewrite” with the key/value pairs "source": "/(.*)" and "destination": "/api" to redirect all traffic to the server entrypoint.

The deploy is successful, but on navigating to the endpoint express-typescript-vercel-template.vercel.app, the compiled javascript code is displayed instead of the root GET result defined in my Express application. Looking at the “Deployment Summary”, the “Static Files” does have an /api/index.js file, but it’s not detecting any frameworks unfortunately, so I’ve definitely went wrong somewhere.

Any help on what mistake I’ve made or improvements to the project structure would be greatly appreciated.

Github repo: 0mn1core/express-typescript-vercel-template

Hi, @omn1coreprocessing-g! Welcome to the Vercel Community, great to have you here. :smile:

I’ve placed all of my code inside of a src folder, with an api directory containing the server entry point index.ts . I’m using tsup to compile my typescript code into javascript code in the dist folder.

It seems like the main issue is that Vercel is treating your compiled JavaScript files as static assets instead of running them as a serverless function. This usually happens because Vercel expects serverless functions to be placed in the api directory at the project root by default, not inside the dist directory.

Sharing this Express template in case it’s helpful:

And a guide:

Hmm, I figured it just needed to be in the output directory, but I guess not. I did try again with a new commit, making tsup instead output the compiled code to an api directory at root level and switching the foldering so the server entrypoint was in the index.ts file nested inside it, as well as setting the “Output Directory” to ./ (if I didn’t have it set, it seems to skip the build), but that also didn’t seem to work. I guess when you actually provide build steps, it breaks whatever capability Vercel has for determining running serverless functions? I tried looking into setting the framework explicitly to get around that, but it doesn’t seem like there’s any framework for express.

It seems like I need to do the compile outside of Vercel, but I also don’t want to check in the compiled files into source control. Could I potentially keep my approach of compiling into api and switch over to using manual github CI actions as described here? Just install tsup/typescript and run build before installing vercel and running the pull/build/deploy commands? Is there an easy way to unlink the integration so that I can try out this approach?

I did check those two sites when originally searching, but they unfortunately don’t cover using typescript as part of the project. Though I do notice that both of them use a .ts file for the index, does Vercel support running typescript straight up as if you were using tsx/tsnode/node with the new typescript support or does it just treat any .ts files as if they were javascript files and not do any compiling?

1 Like

The experiment was a success! Using Github actions, I followed the normal workflow described in the previously mentioned Vercel documentation, but added two beginning commands for npm install --global tsup typescript and npm run build, which creates the app folder with compiled javascript files. It pulls that in and correctly figures out it should be a serverless function. So glad I’m able to get it all set up without having to check in build files!

My one outstanding problem is that the integration is still kicking off its build before the Github action. How do I go about preventing that from happening while still properly keeping the project linked? And would I still be able to get the nice integration that happens for pull requests?

1 Like

I’m going to mark the previous comment as the solution and open a new topic on how to effectively switch from the github integration to manual CI/CD through github actions, since it’s outside the original scope of this topic. If anyone finds this thread through google or other means and is trying to host a typescript/express server on vercel, I’ll eventually be making the repo in the original post into a template repository with documentation on how to stand it up, hopefully it proves helpful in some way.

1 Like

I’ll eventually be making the repo in the original post into a template repository with documentation on how to stand it up, hopefully it proves helpful in some way.

Love to see this! When you’re ready, you can share it under the Community tag to make it easier for folks to find it. Thanks @omn1coreprocessing-g!

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.