matijao/webdev huggingface dataset:
Contributing · Nitro

Contributing

Thank you for wanting to contribute to Nitro 💛

Before everything, please make sure to check the open issues or the discussions.

To contribute locally:

Fork and clone unjs/nitro
Enable corepack using corepack enable (use npm i -g corepack for Node.js < 16.10)
Install dependencies using pnpm install
Activate passive watcher using pnpm stub
Start playground with pnpm dev and open http://localhost:3000
You can also try examples/ using pnpm nitro dev examples/<name> and pnpm nitro build examples/<name>
Make changes
Ensure all tests pass using the pnpm test command
Open a Pull-Request

You can also run pnpm vitest test/presets/node.test.ts to run a single test.

Edit this page on GitHub
Guide
TypeScript
Overview
TypeScript · Nitro

TypeScript Support

Nitro supports TypeScript by default. If you are using the starter template, you have nothing to do ✨.

To add type hints within your project, create a tsconfig.json file:

tsconfig.json
{

  "extends": "./.nitro/types/tsconfig.json"

}

Copy to clipboard

Run npx nitropack prepare to generate the types for global auto-imports. This can be useful in a CI environment or as a postinstall command in your package.json.

If you are using Nuxt, your tsconfig.json can stay:

tsconfig.json
{

  "extends": "./.nuxt/tsconfig.json"

}

Copy to clipboard
Edit this page on GitHub
Guide
Plugins
Community
Contributing
Utils · Nitro

Utils

Nitro helps you to stay organized allowing you to take advantage of the auto-imports feature.

Every export in the utils directory and its subdirectories will become available globally in your application.

Example: Create a utils/sum.ts file where a function useSum is exported:

utils/sum.ts
export function useSum(a: number, b: number) { return a + b }

Copy to clipboard

Use it in your routes/index.ts file without importing it:

routes/index.ts
export default defineEventHandler(() => {

  const sum = useSum(1, 2) // auto-imported

  return { sum }

})

Copy to clipboard
Experimental Composition API

Nitro (2.6+) enables a new server development experience in order to split application logic into smaller "composable" utilities that are fully decoupled from each other and can directly assess to a shared context (request event) without needing it to be passed along. This pattern is inspired from Vue Composition API and powered by unjs/unctx.

This feature is currently supported for Node.js and Bun runtimes and also coming soon to other presets that support AsyncLocalStorage interface.

In order to enable composition API, you have to enable asyncContext flag:

nitro.config.ts
nuxt.config.ts
export default defineNitroConfig({

  experimental: {

    asyncContext: true

  }

});

Copy to clipboard

After enabling this flag, you can use useEvent() (auto imported) in any utility or composable to access the request event without manually passing it along:

with async context
without async context
// routes/index.ts

export default defineEventHandler(async () => {

  const user = await useAuth()

})



// utils/auth.ts

export function useAuth() {

  return useSession(useEvent())

}

Copy to clipboard
Edit this page on GitHub
Guide
Assets
Guide
Plugins
Assets · Nitro

Assets Handling

Nitro handles assets via the public/ directory.

Public Assets

All assets in public/ directory will be automatically served.

public/

  image.png     <-- /image.png

  video.mp4     <-- /video.mp4

  robots.txt    <-- /robots.txt

package.json

nitro.config.ts

Copy to clipboard

When building with Nitro, it will copy the public/ directory to .output/public/ and create a manifest with metadata:

{

  "/image.png": {

    "type": "image/png",

    "etag": "\"4a0c-6utWq0Kbk5OqDmksYCa9XV8irnM\"",

    "mtime": "2023-03-04T21:39:45.086Z",

    "size": 18956

  },

  "/robots.txt": {

    "type": "text/plain; charset=utf-8",

    "etag": "\"8-hMqyDrA8fJ0R904zgEPs3L55Jls\"",

    "mtime": "2023-03-04T21:39:45.086Z",

    "size": 8

  },

  "/video.mp4": {

    "type": "video/mp4",

    "etag": "\"9b943-4UwfQXKUjPCesGPr6J5j7GzNYGU\"",

    "mtime": "2023-03-04T21:39:45.085Z",

    "size": 637251

  }

}

Copy to clipboard

This allows Nitro to know the public assets without scanning the directory, giving high performance with caching headers.

Server Assets

All assets in assets/ directory will be added to the server bundle.

They can be addressed by the assets:server mount point using useStorage('assets:server')

Keys can be written assets/server/my_file_path or assets:server:my_file_path.
Custom Server Assets

In order to add assets from a custom directory, path will need to be defined in the nitro config:

nitro.config.ts
nuxt.config.ts
export default defineNitroConfig({

  serverAssets: [{

    baseName: 'my_directory',

    dir: './server/my_directory'

  }]

})

Copy to clipboard

They can be addressed by the key assets/my_directory/.

Examples

Example: Retrieving a json data from default assets directory:

export default defineEventHandler(async () => {

  const data = await useStorage().getItem(`assets/server/data.json`)

  return data

})

Copy to clipboard

Example: Retrieving a html file from a custom assets directory:

nitro.config.ts
nuxt.config.ts
export default defineNitroConfig({

  serverAssets: [{

    baseName: 'templates',

    dir: './templates' // Relative to `srcDir` (`server/` for nuxt)

  }]

})

Copy to clipboard
// routes/success.ts

export default defineEventHandler(async (event) => {

  return await useStorage().getItem(`assets/templates/success.html`)

  // or

  return await useStorage('assets:templates').getItem(`success.html`)

})

Copy to clipboard
Edit this page on GitHub
Guide
Cache API
Guide
Utils
Storage Layer · Nitro

Storage Layer

Nitro provides a built-in storage layer that can abstract filesystem or database or any other data source.

useStorage() is an instance of createStorage using the memory driver.

Example: Simple (in memory) operations

await useStorage().setItem('test:foo', { hello: 'world' })

await useStorage().getItem('test:foo')



// You can also specify the base in useStorage(base)

await useStorage('test').setItem('foo', { hello: 'world' })

await useStorage('test').getItem('foo')

Copy to clipboard

See Unstorage for detailed usage.

Mountpoints

You can mount storage drivers using the storage option:

nitro.config.ts
nuxt.config.ts
export default defineNitroConfig({

  storage: {

    'redis': {

      driver: 'redis',

      /* redis connector options */

    },

    'db': {

      driver: 'fs',

      base: './data/db'

    }

  }

})

Copy to clipboard
Runtime configuration

In scenarios where the mount point configuration is not known until runtime, Nitro can dynamically add mount points during startup using plugins:

This is a temporary workaround, with a better solution coming in the future! Keep a lookout on the GitHub issue here.
plugins/storage.ts
nitro.config.ts
nuxt.config.ts
import redisDriver from 'unstorage/drivers/redis'



export default defineNitroPlugin(() => {

  const storage = useStorage()



  // Dynamically pass in credentials from runtime configuration, or other sources

  const driver = redisDriver({

      base: 'redis',

      host: useRuntimeConfig().redis.host,

      port: useRuntimeConfig().redis.port,

      /* other redis connector options */

    })



  // Mount driver

  storage.mount('redis', driver)

})

Copy to clipboard

Usage:

await useStorage('redis').setItem('foo', { hello: 'world' })

await useStorage('redis').getItem('foo')

// or

await useStorage().setItem('redis:foo', { hello: 'world' })

await useStorage().getItem('redis:foo')

Copy to clipboard

Usage with generics:

await useStorage().getItem<string>('foo')

// => string

await useStorage<string>().getItem('foo')

// => string



await useStorage<string>().setItem('foo', 123) // ts error



type Foo = { data: number }



await useStorage().getItem<Foo>('foo')

// => Foo

Copy to clipboard

You can find the list of drivers on unstorage documentation.

In development, Nitro adds the cache mountpoint using the FS driver writting to .nitro/cache or .nuxt/cache if using Nuxt.

await useStorage('cache').setItem('foo', { hello: 'world' })

await useStorage('cache').getItem('foo')

Copy to clipboard
Development storage

You can use the devStorage key to overwrite the storage configuration during development, very useful when you use a database in production and want to use the filesystem in development.

nitro.config.ts
nuxt.config.ts
export default defineNitroConfig({

  // Production

  storage: {

    db: {

      driver: 'redis',

      /* redis connector options */

    }

  },

  // Development

  devStorage: {

    db: {

      driver: 'fs',

      base: './data/db'

    }

  }

})

Copy to clipboard
Edit this page on GitHub
Guide
Routing
Guide
Cache API
Configuration · Nitro

Configuration

You can customize your Nitro server with single configuration file: nitro.config.ts.

All deployment providers are built on the same options API.

If you are using Nuxt, use the nitro option in your Nuxt config.

nitro.config.ts
nuxt.config.ts
export default defineNitroConfig({

  // Nitro options

})

Copy to clipboard

Read all the available options to configure Nitro.

Nitro loads the configuration using unjs/c12, giving more possibilities such as using .nitrorc.

.nitrorc
.nuxtrc
timing=true

Copy to clipboard
Runtime Configuration

Nitro provides a runtime config API to expose configuration within your application, with the ability to update it at runtime by setting environment variables.

To expose config and environment variables to the rest of your app, you will need to define runtime configuration in your configuration file.

Example:

nitro.config.ts
nuxt.config.ts
export default defineNitroConfig({

  runtimeConfig: {

    helloThere: "foobar",

  }

})

Copy to clipboard

You can now access the runtime config using useRuntimeConfig(event).

Example:

api/example.get.ts (nitro)
server/api/example.get.ts (nuxt)
export default defineEventHandler((event) => {

  return useRuntimeConfig(event).helloThere // foobar

});

Copy to clipboard
Note: Consider using useRuntimeConfig(event) within event handlers and utilities and avoid calling it in ambient global contexts.
Environment Variables

Nitro supports defining environment variables using .env file in development (use platform variables for production).

Create an .env file in your project root:

.env
TEST="123"

Copy to clipboard

You can universally access environment variables using import.meta.env.TEST or process.env.TEST.

Note: Consider writing any logic that depends on environment variables within event handlers and utilities and avoid accessing and caching them in ambient global contexts.
Update runtime config using environment variables

The variables prefixed with NITRO_ will be applied to runtime config, and they will override the variables defined within your nitro.config.ts file. (matching "camelCase" version).

Example:

.env (nitro)
.env (nuxt)
NITRO_HELLO_THERE="123"

Copy to clipboard
Edit this page on GitHub
Guide
Getting Started
Guide
Auto Imports
Auto Imports · Nitro

Auto Imports

Nitro is using unjs/unimport to auto import utilities when used with full tree-shaking support.

Available Auto Imports
defineCachedFunction(fn, options) / cachedFunction(fn, options)
defineCachedEventHandler(handler, options) / cachedEventHandler(handler, options)
defineRenderHandler(handler)
useRuntimeConfig(event?)
useAppConfig(event?)
useStorage(base?)
useNitroApp()
defineNitroPlugin(plugin)
nitroPlugin(plugin)
getRouteRules(event)

Check the source code for list of available auto imports.

With TypeScript enabled, you can easily see them as global utilities in your IDE.

The types are auto generated for global auto-imports when running the prepare or dev command.
Manual Imports

For some edge cases (IDE support and libraries in node_modules) it is impossible to rely on auto imports.

You can import them from virtual #imports file. It will be still tree-shaken:

plugins/test.ts
import { useStorage } from '#imports'

Copy to clipboard
Edit this page on GitHub
Guide
Configuration
Guide
Routing
Getting Started · Nitro

Getting Started

Let's create a new Nitro app in few steps.

Play Online
Open on Stackblitz
Open on CodeSandbox
Starter Template

Make sure you have installed the recommended setup:

Create a new project using starter template:

npx
pnpm
bun
npx giget@latest nitro nitro-app

Copy to clipboard
cd nitro-app

Copy to clipboard

Install the dependencies:

npm
yarn
pnpm
bun
npm install

Copy to clipboard

Start the development server:

npm run dev

Copy to clipboard

🪄 Your API is ready at http://localhost:3000/

Check .nitro/dev/index.mjs if want to know what is happening

Build your production-ready server:

npm run build

Copy to clipboard

Output is in the .output directory and ready to be deployed on almost any provider with no dependencies.

You can try it locally with:

npm run preview

Copy to clipboard
Nightly Release Channel

Nitro offers a nightly release channel that automatically releases for every commit to main branch.

You can opt-in to the nightly release channel by updating your package.json:

Nitro
Nuxt
{

  "devDependencies": {

--    "nitropack": "^2.0.0"

++    "nitropack": "npm:nitropack-nightly@latest"

  }

}

Copy to clipboard
If you are using Nuxt, use the Nuxt nightly channel as it already includes nitropack-nightly.

Remove the lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, or bun.lockb) and reinstall the dependencies.

Edit this page on GitHub
Guide
Configuration