DEV Community

Paulo
Paulo

Posted on

Fixing a Next.js 16 deployment on Hostinger: glibc, SWC, and Webpack

TL;DR

Errors encountered during deployment:

/lib64/libm.so.6: version `GLIBC_2.29' not found
Failed to load next.config.ts
Enter fullscreen mode Exit fullscreen mode

After switching the configuration to JavaScript, the remaining error was:

Only WebAssembly (WASM) bindings were loaded,
and Turbopack requires native bindings.
Enter fullscreen mode Exit fullscreen mode

The fix that worked for mine Next.js 16.3.5 deployment:

  1. Rename next.config.ts to next.config.mjs. Remove the TypeScript type import and replace const nextConfig: NextConfig = with const nextConfig =. Preserve all existing settings and export default nextConfig.
  2. Change the build script in package.json:
   - "build": "next build",
   + "build": "next build --webpack",
Enter fullscreen mode Exit fullscreen mode
  1. Commit and push both changes, then redeploy. Keep Hostinger's build command as npm run build, output directory as .next, and Node.js selection as 22.x.

The .mjs configuration avoids TypeScript transformation during configuration
loading. Webpack allows the build to proceed with the available SWC WASM fallback.
No webpack: true setting, Next.js downgrade, or manual glibc upgrade was needed.

How the issue unfolded

While deploying the website to Hostinger, I ran into a build failure that initially looked like a broken Next.js configuration file.

The project built locally. On Hostinger, the log mentioned a missing temporary configuration module, along with an error about GLIBC_2.29. Changing the configuration format got the build further, but it took a second change to get past the actual compiler limitation.

The working combination was:

  • Use next.config.mjs instead of next.config.ts.
  • Run the production build with next build --webpack.

Here is how the errors led to those changes.

The environment

The website uses Next.js App Router, TypeScript, React, and CSS Modules. The relevant versions and deployment settings were:

Setting Value
Next.js 16.3.5
React 19.2.8
Local operating system Windows
Local Node.js 22.20.0
Local npm 11.6.1
Hostinger Node.js selection 22.x
Hostinger build command npm run build
Root directory ./
Output directory .next

The exact Node.js patch version and npm version used by the remote builder were not established. The versions above distinguish what was checked locally from what was selected in Hostinger's deployment panel.

The first failure: configuration loading

The original build attempted to load next.config.ts and failed. These were the useful parts of the log, with account-specific paths omitted:

Attempted to load @next/swc-linux-x64-gnu
/lib64/libm.so.6: version `GLIBC_2.29' not found

Attempted to load @next/swc-linux-x64-musl
/lib64/libc.so: invalid ELF header

Failed to load next.config.ts
Enter fullscreen mode Exit fullscreen mode

A later message referred to a missing generated configuration module. Hostinger's automated analysis suggested deleting a corrupted temporary configuration file.

That explanation did not account for the earlier native-library errors. A generated filename alone was not evidence that the configuration had become corrupted, and clearing the Next.js cache would not provide the missing system-library interface.

Why a TypeScript project was complaining about Linux libraries

SWC is the compiler used by Next.js to transform application code. Its native binaries depend on the operating system they run on.

glibc is the GNU C Library, a foundational library used by many Linux programs. The reported failure involved its math library, libm.so.6. The SWC binary needed the versioned interface named GLIBC_2.29, which the loaded library did not provide.

I connected through SSH and ran:

getconf GNU_LIBC_VERSION
Enter fullscreen mode Exit fullscreen mode

The result was:

glibc 2.28
Enter fullscreen mode Exit fullscreen mode

This confirmed the library version in the SSH session. It did not prove that the deployment builder and SSH session were identical environments, but the build log independently confirmed the missing interface in the builder.

Neither changing the project's npm dependencies nor selecting a newer Node.js version necessarily upgrades the Linux libraries underneath them. Manually replacing glibc in a managed hosting account was not an appropriate fix.

First change: load the configuration as JavaScript

I converted next.config.ts to next.config.mjs.

The opening lines changed from:

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // Existing settings
};

export default nextConfig;
Enter fullscreen mode Exit fullscreen mode

to:

/** @type {import("next").NextConfig} */
const nextConfig = {
  // Existing settings, unchanged
};

export default nextConfig;
Enter fullscreen mode Exit fullscreen mode

These are excerpts illustrating the conversion. I preserved the real configuration body, including its security headers and conditional Docker output setting.

The .mjs extension identifies a JavaScript module that Node.js can load without transforming TypeScript syntax. The JSDoc comment retains editor type information. Next.js supports this configuration format. Next.js configuration documentation.

Only the configuration file changed language. The application remained TypeScript.

After committing and pushing the rename, the next deployment confirmed that this step worked:

✓ Running next.config.mjs took 27ms
Enter fullscreen mode Exit fullscreen mode

The second failure made the remaining problem clearer

Configuration loading succeeded, but the production build still failed. This time the log showed that Next.js had selected the WebAssembly fallback for SWC:

Using cached swc package @next/swc-wasm-nodejs...
Enter fullscreen mode Exit fullscreen mode

It then explained the limitation:

Turbopack is not supported on this platform (linux/x64)
because native bindings are not available.
Only WebAssembly (WASM) bindings were loaded,
and Turbopack requires native bindings.
Enter fullscreen mode Exit fullscreen mode

Turbopack and Webpack are bundlers: they assemble application code and assets into build output. In this deployment, Next.js was using Turbopack, which could not operate with the available WASM bindings. The error explicitly recommended switching to Webpack. Turbopack documentation.

This also explained why changing the configuration extension was only part of the solution. It removed the first obstacle without changing the bundler used for the rest of the build.

Second change: select Webpack in the build command

In package.json, I changed one script:

- "build": "next build",
+ "build": "next build --webpack",
Enter fullscreen mode Exit fullscreen mode

The final scripts were:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build --webpack",
    "start": "next start",
    "lint": "eslint .",
    "typecheck": "next typegen && tsc --noEmit"
  }
}
Enter fullscreen mode Exit fullscreen mode

--webpack is the supported CLI option for selecting Webpack. A suggestion from the automated analysis to add webpack: true to the configuration was incorrect: that configuration property is a customization hook, not a boolean bundler selector. Next.js CLI documentation.

I kept Hostinger's build command as npm run build; it now invoked the updated script. The output directory stayed .next, and Node.js stayed at 22.x. Local development continued to use the default bundler through next dev.

There was no need to install Webpack separately, downgrade Next.js, rewrite the application in JavaScript, or upgrade glibc manually.

Validation and result

Before redeploying, these checks passed locally:

npm run lint
npm run typecheck
npm run build
Enter fullscreen mode Exit fullscreen mode

The local production build identified the selected bundler as:

▲ Next.js 16.3.5 (webpack)
Enter fullscreen mode Exit fullscreen mode

The local checks validated the project changes; they did not reproduce Hostinger's Linux environment. The subsequent Hostinger deployment worked after the changes were pushed and redeployed.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.