Ver en Español
Plugins in Next.js
Apr 11, 2023
Updated: Jun 25, 2026

Plugins in Next.js

The next.config.js file gives us the ability to do some very powerful things. Because the config file follows a convention, rules every Next.js project shares, it's easy to inject code written by others, which is exactly what we'll call Plugins.

Valid as of Next.js 16: The concept of composing your configuration in next.config.js is still fully valid, next.config.js can export either an object or a function that receives and returns the config. What changed since 2022 are the specific packages: several that were common back then are now unmaintained. Throughout this post I point you to the modern alternative in each case.

Making our app available offline

Historically, to make an app work offline you'd use the next-offline plugin, wrapping your configuration like this:

//  Legacy pattern: 'next-offline' is no longer maintained.
const withOffline = require('next-offline');

const config = {
  // Whatever goes in your configuration
};

module.exports = withOffline(config);

`next-offline` is deprecated. It hasn't been maintained for years and predates the App Router. For PWA / service workers on Next.js 16, use `next-pwa` (Pages Router) or Serwist / your own service worker (App Router). The "wrap the config" pattern above is what matters to learn here; only the package changes.

Composing multiple plugins

Most plugins follow the `withPluginName` convention: they take your Next.js config, wrap it, and return it in the expected format. That lets you apply a composition pattern when you want to use several plugins at once.

It used to be common to reach for a package like next-compose-plugins for this. Today that package is archived too, and the good news is you no longer need it: since each plugin is just a function, you can compose them by hand.

// Manual composition — no extra dependencies (recommended on Next.js 16)
const withOffline = require('next-offline');
const withReactSvg = require('next-react-svg');

const config = {
  env: {
    MY_ENV: process.env.MY_ENV,
  },
};

// Each plugin is a (config) => config function, so just nest them:
module.exports = withOffline(
  withReactSvg({
    ...config,
    // next-react-svg specific configuration
  }),
);

If you have many plugins and prefer something more readable, you can compose them with a reduce:

// reduce alternative — equivalent, no dependencies
const plugins = [withReactSvg, withOffline];

module.exports = plugins.reduce((acc, plugin) => plugin(acc), config);

As you can see, chaining plugins in Next.js is still wonderfully natural, and now with one less dependency.

Handling environment variables with .env

Here's a big simplification compared to 2022. You no longer need any plugin (next-env, dotenv-load, etc.) to read environment variables: Next.js automatically loads .env files as of version 9.4. You just create the file.

Create a .env.local at the root of your project and add your variables:

# .env.local
NEXT_PUBLIC_APP_URL=https://www.sebastian-gomez.com

Important tip: Variables you want to use in the browser must be prefixed with NEXT_PUBLIC_. Without that prefix, the variable only exists on the server and arrives as undefined on the client. Also, keep your secrets out of version control: never commit your .env.local to GitHub.

Now, to use the variable in any page or component, just read process.env:

// The variable is prefixed with NEXT_PUBLIC_ so it's available on the client
<a
  className="text-pink-600 cursor-pointer hover:underline"
  href={process.env.NEXT_PUBLIC_APP_URL}
>
  Go to the app
</a>

Conclusions

  • Plugins are a simple, powerful way to extend Next.js, and the next.config.js composition pattern is still valid on Next.js 16.
  • The `withPluginName` convention makes it easy and natural to chain multiple plugins, and today you can compose them by hand, with no extra packages.
  • For environment variables you no longer need any plugin: use the built in .env support, and remember the NEXT_PUBLIC_ prefix to safely expose them to the browser.

Suggested exercises

  1. Create a basic Next.js 16 project and integrate a plugin of your choice (for example next-pwa). Read its docs and configure it correctly.
  2. Add two different plugins to your project and compose them by hand (nesting functions or with reduce), making sure they work together.
  3. Create a .env.local file with at least three variables; expose one to the client with NEXT_PUBLIC_ and verify the others only exist on the server.

3-point summary

  1. Next.js plugins make it easy to inject extra functionality following the withPluginName convention.
  2. You can combine multiple plugins with manual function composition, you no longer need with-compose-plugins (it's archived).
  3. Environment variables are handled with built in .env support; use NEXT_PUBLIC_ for the ones you need in the browser.

I hope this post is useful to you and that you can apply it to a project you have in mind, or that it simply helped you understand how plugins work and how to improve the configuration of your Next.js projects.

Leave me a comment if it helped, if you want to add an opinion, or if you have any questions. And remember, if you liked it, you can also share it using the social links below.

Sebastian Gomez

Sebastian Gomez

Creador de contenido principalmente acerca de tecnología.

Leave a Reply

0 Comments

Advertisements

Related Posts

Categorias