DEV Community

Viktor Pasynok
Viktor Pasynok

Posted on

How to create scalable, module-based applications with ease.

Modern applications thrive on modular architecture, adapting seamlessly to evolving business needs. To achieve true modularity, though, you need more than just independent components—you need an efficient way to bring them together. This means controlling how modules load, in what order, and with which dependencies. It gets even trickier when you want to turn off parts of the system without any traces in the code, like if/else statements, and without affecting the stability of other components.

The simplest example: imagine your application has numerous interconnected features. Sometimes, you need to disable one of them. Here’s the catch: some features may directly depend on it, while others may be affected indirectly (transitively). If you overlook these dependencies, your app might crash. And if you need to disable more than one feature, the combinations can become complex and error-prone. It would be ideal to have a way to explicitly describe feature dependencies and safely disable them without missing anything.

For instance, like this

const user = createContainer({
  id: 'user',
  start: async () => {
    const data = await fetchUser();

    return { api: { data } };
  },
});

const accounts = createContainer({
  id: 'accounts',
  dependsOn: [user],
  start: async ({ user }) => {
    const data = await fetchAccounts({ id: user.data.id });

    return { api: { data } };
  },
  enable: ({ user }) => user.data.id !== null,
});

const wallets = createContainer({
  id: 'wallets',
  dependsOn: [accounts],
  start: () => ({ api: null }),
});
Enter fullscreen mode Exit fullscreen mode

...and expect something like this:

compose.up start

user: 'idle',     accounts: 'idle',     wallets: 'idle'
user: 'pending',  accounts: 'idle',     wallets: 'idle'
user: 'done',     accounts: 'idle',     wallets: 'idle'

# if user.data.id
user: 'done',    accounts: 'pending',  wallets: 'idle'
user: 'done',    accounts: 'done',     wallets: 'pending'
user: 'done',    accounts: 'done',     wallets: 'done'

# else
user: 'done',    accounts: 'off',      wallets: 'off'

compose.up done
Enter fullscreen mode Exit fullscreen mode

I created the @grlt-hub/app-compose library, which makes this a reality.

The library offers convenient functions for creating and composing modules into a single system. Each module is encapsulated in a container with a clear configuration, including parameters like id, dependsOn, optionalDependsOn, start, and enable. Developers describe containers and launch them using compose.up fn, without the need to worry about the order of execution. This approach makes working with containers intuitive and close to natural language.

  • Provides a simple and intuitive developer experience (DX).
  • Designed with a focus on quality and performance.
  • Weighs less than 1.5 kB, making it lightweight.
  • Covered by 100% tests, including type tests.
  • Ensures high performance, suitable for scalable applications.
  • Includes debugging tools to facilitate the development process.
  • Offers the ability to visualize the system composed of containers effectively (including transitive dependencies and their paths).
  • Follows semantic versioning (semver), guaranteeing stability and predictability of changes with each release.

Ready to simplify your modular architecture? Dive into app-compose and experience efficient, scalable dependency management. Check it out and let us know how it transforms your projects!

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more