Problem: Dynamically Load a Database Client Using ES Modules

Medium
30 min
Use dynamic import() to load and instantiate a database client at runtime based on configuration.

Problem statement

You’re building a backend that runs in multiple environments. In development, it should use an in-memory SQLite client. In production, a PostgreSQL client. But unlike before, each client is defined in a separate module (./sqlite.js and ./postgres.js).

You need to implement a dynamic factory that uses the import() function to load the correct module and return the instantiated client. This must happen inside a factory function so that consumers don’t worry about imports or setup—they just call await createDbClient(env).

Goal

Implement createDbClient(env) in createDbClient.js to dynamically import and return the correct client instance from either sqlite.js or postgres.js, based on the provided env. In index.js, consumers should be able to call createDbClient('dev') or createDbClient('prod') without knowing which module was loaded.

Constraints

  • Do not use if, switch, or ternaries to select modules.

  • Do not statically import sqlite.js or postgres.js.

  • Use dynamic import() based on a map defined inside createDbClient.js.

  • Instantiate and return the client inside the factory—nowhere else.

  • Consumers (e.g., in index.js) must not know which module was loaded.

Sample output

The examples below illustrate what the output should look like:

import { createDbClient } from './createDbClient.js';
const run = async () => {
const devClient = await createDbClient('dev');
console.log(devClient.query('SELECT * FROM users'));
const prodClient = await createDbClient('prod');
console.log(prodClient.query('SELECT * FROM orders'));
};
run();
/* Expected output:
SQLite: SELECT * FROM users
Postgres: SELECT * FROM orders */

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Problem: Dynamically Load a Database Client Using ES Modules

Medium
30 min
Use dynamic import() to load and instantiate a database client at runtime based on configuration.

Problem statement

You’re building a backend that runs in multiple environments. In development, it should use an in-memory SQLite client. In production, a PostgreSQL client. But unlike before, each client is defined in a separate module (./sqlite.js and ./postgres.js).

You need to implement a dynamic factory that uses the import() function to load the correct module and return the instantiated client. This must happen inside a factory function so that consumers don’t worry about imports or setup—they just call await createDbClient(env).

Goal

Implement createDbClient(env) in createDbClient.js to dynamically import and return the correct client instance from either sqlite.js or postgres.js, based on the provided env. In index.js, consumers should be able to call createDbClient('dev') or createDbClient('prod') without knowing which module was loaded.

Constraints

  • Do not use if, switch, or ternaries to select modules.

  • Do not statically import sqlite.js or postgres.js.

  • Use dynamic import() based on a map defined inside createDbClient.js.

  • Instantiate and return the client inside the factory—nowhere else.

  • Consumers (e.g., in index.js) must not know which module was loaded.

Sample output

The examples below illustrate what the output should look like:

import { createDbClient } from './createDbClient.js';
const run = async () => {
const devClient = await createDbClient('dev');
console.log(devClient.query('SELECT * FROM users'));
const prodClient = await createDbClient('prod');
console.log(prodClient.query('SELECT * FROM orders'));
};
run();
/* Expected output:
SQLite: SELECT * FROM users
Postgres: SELECT * FROM orders */

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Node.js
import { createDbClient } from './createDbClient.js';
const run = async () => {
const devClient = await createDbClient('dev');
console.log(devClient.query('SELECT * FROM users'));
const prodClient = await createDbClient('prod');
console.log(prodClient.query('SELECT * FROM orders'));
};
run();
/* Expected output:
SQLite: SELECT * FROM users
Postgres: SELECT * FROM orders */