{"id":10529,"library":"avvio","title":"Avvio: Asynchronous Application Bootstrapping","description":"Avvio is a robust, reentrant, and graph-based library designed for managing the asynchronous bootstrapping of Node.js applications. It simplifies complex application startup sequences by handling plugin loading order, inter-plugin dependencies, and comprehensive error management automatically. Unlike simpler sequential loaders, Avvio allows plugins to register other plugins, ensuring correct execution flow within deeply nested structures. The current stable version is 9.2.0, with a release cadence of minor and patch updates every few weeks or months, often driven by dependency updates or minor feature enhancements. Its key differentiator is its emphasis on reentrancy and a dependency graph, which guarantees that even deeply nested plugins are initialized in the precise order required, coupled with sophisticated error handling capabilities.","status":"active","version":"9.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/fastify/avvio","tags":["javascript","async","boot","delayed","open","typescript"],"install":[{"cmd":"npm install avvio","lang":"bash","label":"npm"},{"cmd":"yarn add avvio","lang":"bash","label":"yarn"},{"cmd":"pnpm add avvio","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While CommonJS `require('avvio')` is still prevalent in older Node.js projects and some examples, modern projects should prefer ESM `import avvio from 'avvio'`. The library ships with TypeScript types for both.","wrong":"const avvio = require('avvio')","symbol":"avvio","correct":"import avvio from 'avvio'"},{"note":"The `Avvio` type can be imported from the package for TypeScript users to correctly type the application instance managed by Avvio, allowing for type-safe plugin registration and usage.","symbol":"Avvio","correct":"import { Avvio } from 'avvio'; const app: Avvio<MyApplicationInstance> = avvio(myAppInstance);"},{"note":"Users familiar with Fastify might mistakenly use `app.register` for Avvio plugins. Avvio's method for registering plugins is `app.use`.","wrong":"app.register(myPlugin, options)","symbol":"use","correct":"app.use(myPlugin, options)"}],"quickstart":{"code":"'use strict'\n\nconst avvio = require('avvio')\nconst app = avvio()\n\napp\n  .use(first, { hello: 'world' })\n  .after((err, cb) => {\n    if (err) {\n      console.error('Error in after hook:', err);\n      return cb(err);\n    }\n    console.log('after first and second')\n    cb()\n  })\n\napp.use(third)\n\napp.ready(function (err) {\n  // the error must be handled somehow\n  if (err) {\n    throw err\n  }\n  console.log('application booted!')\n  // In a real app, you might start listening for requests here\n  // For demonstration, we'll close the app immediately\n  app.close().then(() => console.log('application closed.')).catch(e => console.error('Error closing:', e));\n})\n\nfunction first (instance, opts, cb) {\n  console.log('first loaded', opts)\n  instance.use(second)\n  cb()\n}\n\nfunction second (instance, opts, cb) {\n  console.log('second loaded')\n  process.nextTick(cb)\n}\n\n// async/await or Promise support\nasync function third (instance, opts) {\n  console.log('third loaded')\n  // Simulating async work\n  await new Promise(resolve => setTimeout(resolve, 50));\n}\n\n","lang":"javascript","description":"This example demonstrates how to initialize Avvio, register a series of asynchronous plugins including nested ones and those leveraging async/await syntax, and then wait for the application to be fully booted before gracefully closing it."},"warnings":[{"fix":"Upgrade your Node.js runtime to a currently supported Long Term Support (LTS) version, typically Node.js 18 or newer, to be compatible with Avvio v9.x and benefit from its latest features and security patches.","message":"Avvio v9.0.0 introduced breaking changes by dropping support for several End-of-Life Node.js versions. Applications running on older or unsupported Node.js runtimes will need to upgrade their Node.js environment to use Avvio v9.x or later.","severity":"breaking","affected_versions":">=9.0.0"},{"fix":"Ensure all plugins complete their asynchronous operations promptly. For long-running initialization tasks, consider increasing the `timeout` option during Avvio initialization (e.g., `avvio({}, { timeout: 10000 })`) or refactor plugins to optimize their initialization speed.","message":"Plugins can time out if they take longer than the configured `timeout` option to complete their initialization, leading to an `AVV_ERR_READY_TIMEOUT` error. While the default `timeout` is `0` (disabled), setting it to a non-zero value without careful consideration can cause unexpected startup failures if plugins exceed the configured duration.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Standardize on either callback-based plugins (always invoke `cb()`) or Promise-based plugins (always return a Promise, implicitly or explicitly). If an `async` function is used, ensure it *only* returns a Promise and does not also call `cb()`.","message":"While Avvio supports both callback-style and Promise-returning (async/await) plugins, mixing them in a way where an `async` function still calls `cb()` can lead to unexpected behavior, double-done situations, or hung applications. It's crucial to be consistent.","severity":"gotcha","affected_versions":">=7.0.0"},{"fix":"For Avvio versions older than 9.1.0, always call the callback (`cb()`) even for synchronous plugins. For Avvio v9.1.0 and newer, synchronous plugins can simply omit the callback call if they perform no asynchronous operations.","message":"Prior to v9.1.0, even synchronous plugins were expected to call a callback to signal completion. Avvio v9.1.0 introduced support for synchronous plugins that *do not* call a callback, meaning older versions would hang indefinitely if a synchronous plugin omitted the callback.","severity":"breaking","affected_versions":"<9.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Increase the `timeout` option when initializing Avvio (e.g., `avvio({}, { timeout: 15000 })`) or, preferably, debug the plugin to identify and resolve performance bottlenecks that are causing the delay.","cause":"A plugin's initialization function (either its callback or its returned Promise) did not resolve within the `timeout` duration configured during Avvio instantiation.","error":"AVV_ERR_READY_TIMEOUT: Plugin timed out after Xms"},{"fix":"Replace `app.register(myPlugin, options)` with `app.use(myPlugin, options)` as Avvio's plugin registration method is named `use`.","cause":"Attempting to use `app.register` to add plugins, a method commonly found in the Fastify framework, instead of Avvio's `app.use` method.","error":"TypeError: app.register is not a function"},{"fix":"Ensure correct ESM import syntax: `import avvio from 'avvio'; const app = avvio();`. If using CommonJS, ensure `const avvio = require('avvio'); const app = avvio();`.","cause":"This error typically occurs when using TypeScript or transpiled JavaScript, indicating an incorrect default import from a CommonJS module or an attempt to call the `default` export incorrectly.","error":"TypeError: (0 , avvio_1.default) is not a function"},{"fix":"Examine the `after` hook function to identify any long-running or blocking operations. Either optimize the hook's performance, or increase the global `timeout` option if the delay is expected and acceptable.","cause":"An `after` hook, which runs after a set of plugins, failed to complete its execution (call its callback or resolve its Promise) within the configured timeout duration.","error":"Error: AVV_ERR_HOOK_TIMEOUT: Hook 'after' timed out after Xms"}],"ecosystem":"npm"}