Photo by Jefferson Santos on Unsplash

TypeORM and Mysql Configuration for NestJS — Part 2

neil u malgaonkar
Feb 11 · 7 min read

In the last article, I described how to configure the NestJS application to work with Mysql using TypeORM. The approach mentioned in the article is good enough to build a quick prototype or during learning of the NestJS framework. But there are some significant cons with this approach. Let’s do some coding before I explain the cons of the mentioned approach.

In the previous article, we made sure that our code accepts the database configurations from the .env file and successfully connecting to the database and nothing else. Let’s change that.

We will start with defining the User entity.

Let’s TypeORM configuration. I have highlighted the changes in italic bold

Let’s concentrate on the synchronize attribute of the TypeORM configuration object. What synchronize attributes do is it tells TypeORM to automatically create or update the tables in the database based on the entity classes passed to the entities attribute of the configuration object.

We can quickly verify this by running yarn run start:dev and checking the command line for any errors. You can also connect to the database via the command line or using some other GUI tools to verify it is working, as I have explained above.

If you add or remove columns from User entity and save the code, update the database table on server restart (which happens on every save). If you are a fresher, then there is a good chance that you will find this feature very appealing, and it is; if you are using this approach for learning NestJS or building a quick prototype. But this feature is a BIG NO-NO in a real project.

Let’s see why this is not a good idea

  1. Since database schema is updated automatically, it is challenging for other participants of the project to know what changed in the schema and when
  2. As the project gets older, the database schema goes through multiple iterations. With automatic schema update maintaining the schema versions become impossible.
  3. And the most important of all is running test cases. The CD/CI has become a most important part of today's project development. Imagine a scenario where you are tasked with writing test cases for the NestJs project, which uses synchronized option. As per my understanding of TypeORM, right now, there is no way to use synchronized option to revert the database schema while running test cases.

Luckily for us, TypeORM already supports migrations, and you can run it from cli. But there is one caveat. The TypeORM cli will always look for typeormconfig.js file at the root of the project, or you can pass a path of typeormconfig.js file to the cli command. In our case, we have already got rid of typeormconfig.js file and moved its configurations to .env file. Then you might ask, “How can we fix it?”. Well, let me try my best to explain how we can achieve it. We don’t need any new modules or install any new packages. We already have installed that plugin i.e. @nestjs/config. Let’s see how to utilize it to achieve our goal.

Please follow the steps mentioned below.

So, now we are done with defining the application configuration. Let’s see how we can use the application config now. We will start by updating app.module.ts

Let’s check out the app.config.ts and database.config.ts files. Before I start, let me be clear something, app.config.ts file is not really necessary. I have added this file to create a central configuration object that can be used throughout the project. Now let’s check the database config file. Please carefully verify the database config structure and compare it with the object defined in typeormconfig.js file. It is done on purpose. I will get back to it later in the article.

Now, we will move on to the app.module.ts file. I have added numbered points to the above code, and I will try to explain one by one below

  1. ConfigService is a service exposed by NestJS’s config module. We will use this service to access environment variables. e.g. configService.get('ENV_VARIABLE_NAME')
  2. In the previous example, we used the default config module invocation, which automatically loads the .env file from the project's root. Here, we have replaced it with a little different version, which does a few more things. isGlobal attribute makes the ConfigModule global
  3. load attribute is an interesting one. What it does is it takes an array of functions, which will be called once ConfigModule is loaded. e.g., have a look at the app.config.ts file
  4. This is very much similar to our first approach. But here, instead of directly accessing, env we will use ConfigService exported by ConfigModule. Before we proceed ahead, we need to make sure that ConfigModule is being imported in the TypeORM.forRootAsync call, and we need to inject ConfigService to make it available in useFactory function.

The changes that we have made till now has just made the previous implementation elegant. Also, we have set the base for running migrations from the command line.

Let’s create a new file called typeorm.config.ts in config folder

What we have done above is, import the database configurations needed for the typeorm. If you have paid attention until now, you will realize that we haven’t imported typeorm.config.ts file in any of NestJS’s modules. It is because we will use this file as a configuration for TypeORM’s cli tool.

Another important thing to notice in the above code is, we have explicitly imported dotenv package and called dotenv.config() function, which parses the .env file from the root of the project and makes .env variable available in the code execution context. We have to do this because when we run migrations from cli, we are not running them in the NestJS’s ecosystem, but rather, we are accessing the regular .ts file, which is unware of the NestJS existence.

Now, the last step is to update package.json file. I have added things that are needed for the migrations to run successfully in the snippet below.

If you check the snippet carefully, you will notice that most of the commands take --config argument, and it points to the typeorm.config.ts created in config folder.

If you want more information regarding migrations, then please visit the TypeORM's migrations section here.

I have uploaded the complete code on Github, which you can find out here. I have structured code slightly differently on the Github repository, but the central concept is still the same.

Geek Culture

Proud to geek out.

Sign up for Geek Culture Hits

By Geek Culture

Subscribe to receive top 10 most read stories of Geek Culture — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Geek Culture

A new tech publication by Start it up (

neil u malgaonkar

Written by

developer by accident , web programmer by choice , loves reading , eating and talking , currently works with @Bombayworks

Geek Culture

A new tech publication by Start it up (

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store