# How to use Babylon with Next JS

**URL:** <https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665>\
**Category:** Questions\
**Created:** [January 12, 2022, 11:25am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665 "2022-01-12T11:25:16Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![John\_Carlisle](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/john_carlisle/32/21156_2.png) [@John\_Carlisle](https://forum.babylonjs.com/u/John_Carlisle)\
**Post date:** [January 12, 2022, 11:25am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/1 "2022-01-12T11:25:16Z")

</div>

Hi im new to the forum. Could someone help me with a step by step guide on how to use Babylon with Nextjs. I just need a simple example/tutorial beginning with what to install and how to write the code into a Nextjs index.js file so i can render it on the browser. Thanks to everyone in advance

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [January 12, 2022, 5:33pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/2 "2022-01-12T17:33:48Z")

</div>

No sure we have a tuto for it but I think @RaananW is pretty familiar with Next and might have pointers

---

<div class="post-metadata">

**Author:** ![jgonzosan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jgonzosan/32/10007_2.png) [@jgonzosan](https://forum.babylonjs.com/u/jgonzosan)\
**Post date:** [January 12, 2022, 5:40pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/3 "2022-01-12T17:40:49Z")

</div>

I’ve used Babylon with NextJS. This is an example component I’ve used:

```auto
import { Engine, Scene } from "babylonjs";
import React, { useEffect, useRef, useState } from "react";

const BabylonScene = (props) => {
  const reactCanvas = useRef(null);
  const {
    antialias,
    engineOptions,
    adaptToDeviceRatio,
    sceneOptions,
    onRender,
    onSceneReady,
    ...rest
  } = props;

  const [loaded, setLoaded] = useState(false);
  const [scene, setScene] = useState(null);

  useEffect(() => {
    if (window) {
      const resize = () => {
        if (scene) {
          scene.getEngine().resize();
        }
      };
      window.addEventListener("resize", resize);

      return () => {
        window.removeEventListener("resize", resize);
      };
    }
  }, [scene]);

  useEffect(() => {
    if (!loaded) {
      setLoaded(true);
      const engine = new Engine(
        reactCanvas.current,
        antialias,
        engineOptions,
        adaptToDeviceRatio
      );
      const scene = new Scene(engine, sceneOptions);
      setScene(scene);
      if (scene.isReady()) {
        props.onSceneReady(scene);
      } else {
        scene.onReadyObservable.addOnce((scene) => props.onSceneReady(scene));
      }

      engine.runRenderLoop(() => {
        if (typeof onRender === "function") {
          onRender(scene);
        }
        scene.render();
      });
    }

    return () => {
      if (scene !== null) {
        scene.dispose();
      }
    };
  }, [reactCanvas]);

  return (
    <canvas
      style={{ width: "100%", height: "100%" }}
      ref={reactCanvas}
      {...rest}
    />
  );
};

export default BabylonScene;

```

Here is how I used it with a custom imported model:

```auto
import React from "react";
import { SceneLoader } from "babylonjs";
import "babylonjs-loaders";
import BabylonScene from "./BabylonScene";

const onSceneReady = (scene) => {
  console.log("running");
  scene.createDefaultCamera(true);
  SceneLoader.Append(
    "path to 3d model/",
    "Cafe.glb",
    scene,
    (meshes) => {
      scene.activeCamera = meshes.cameras[1];
    }
  );

  return scene;
};

const onRender = (scene) => {};

const CafeBanner = () => {
  return (
    <BabylonScene
      antialias
      onSceneReady={onSceneReady}
      onRender={onRender}
      id="my-canvas"
    />
  );
};

export default CafeBanner;

```

I believe when I created this I was following this in the documentation: [Babylon.js and React | Babylon.js Documentation](https://doc.babylonjs.com/extensions/Babylon.js+ExternalLibraries/BabylonJS_and_ReactJS)

---

<div class="post-metadata">

**Author:** ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)\
**Post date:** [January 12, 2022, 6:10pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/4 "2022-01-12T18:10:22Z")

</div>

The code @jgonzosan offered seems like a perfect starting point.  
As Next.js is technically a static react generator, you might also be able to use @brianzinn’s babylon-react component, but I haven’t tried it yet, so I can’t offer any advice on that.

---

<div class="post-metadata">

**Author:** ![jgonzosan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jgonzosan/32/10007_2.png) [@jgonzosan](https://forum.babylonjs.com/u/jgonzosan)\
**Post date:** [January 12, 2022, 6:19pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/5 "2022-01-12T18:19:03Z")

</div>

I updated my original response as it was only half of how I used it. The BabylonScene component is essentially a “template” that can be used as the basis for a more customized component. The code I posted includes a 3d scene of a cafe I imported.

---

<div class="post-metadata">

**Author:** ![brianzinn](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/brianzinn/32/28013_2.png) [@brianzinn](https://forum.babylonjs.com/u/brianzinn)\
**Post date:** [January 12, 2022, 6:29pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/6 "2022-01-12T18:29:30Z")

</div>

hi @John_Carlisle (and thanks @RaananW for the mention).

I have a sample repo here:

> **[GitHub - brianzinn/nextjs-with-reactbabylonjs](https://github.com/brianzinn/nextjs-with-reactbabylonjs/)**
>
> Contribute to brianzinn/nextjs-with-reactbabylonjs development by creating an account on GitHub.

If you don’t want to use the react renderer and prefer imperative as posted above then have a look at the `babylonjs-hook` branch. You are going to have better tree-shaking results right now until I get a v4 out on `react-babylonjs` with dynamic registration.

Definitely have a look at the next.config.js require on `next-transpile-modules` - you can actually remove the `withTM ` parth completely and go like this:

```auto
import dynamic from 'next/dynamic'

```

then in page/index.tsx change

```auto
import Wave from '../components/elements/Wave/Wave'

```

to

```auto
const Wave = dynamic(() => import('../components/elements/Wave/Wave'), {
  ssr: false
})

```

That repo is a year old, but would appreciate if you have any updates and would accept any PRs to bring up-to-date.

The bundle analyzer is on for that project - have a look at the output if you want to optimize the output. Make sure all of your imports are explicit to file. ie: don’t import from `@babylonjs/core`, but `@babylonjs/core/fullPathHere`

cheers.

---

<div class="post-metadata">

**Author:** ![ecoin](https://avatars.discourse-cdn.com/v4/letter/e/8e7dd6/32.png) [@ecoin](https://forum.babylonjs.com/u/ecoin)\
**Post date:** [January 12, 2022, 11:05pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/7 "2022-01-12T23:05:04Z")

</div>

With Next.js you should only dynamically import Babylon.js because some packages may cause error when loaded in Node.js.

Next.js uses Node.js on the server side, it will load your code twice, in Node.js first, and then in browser, but the code will only run in browser.

Even if you do not have packages that may break in Node.js, it will still be slower to serve the static pages, than if you skipped loading Babylon from backend.

Here is what I use for any React component that imports anything from Babylon:

**Next.js page file**

```auto
/* next/pages/index.js */
import { ClientOnly, dynamicImportOptions } from 'client/utils/next'
import dynamic from 'next/dynamic'

// This is the component that imports something from Babylon.js
const BabylonComponent= dynamic(() => import(`../BabylonComponent`), dynamicImportOptions)

export default function HomePage (props) {
  return <ClientOnly {...props}>{BabylonComponent}</ClientOnly>
}

```

**Utility file**

```auto
/* client/utils/next */
import React, { useEffect, useState } from 'react'
import Loading from 'Loading' // Your custom Loading placeholder component (i.e. show spinner)

// @Note: next.js dynamic import only works for React Components,
// and only starts loading when the Component gets called
export const dynamicImportOptions = {ssr: false, loading: () => <Loading loading/>}

/**
 * HOC Wrapper to Render given React Function Component on client side only
 */
export function ClientOnly ({children: Component, ...props}) {
  const [mounted, setMounted] = useState(false)
  useEffect(() => setMounted(true))
  return mounted && <Component {...props}/>
}

```

I might have some time later to create github template (right now stapped for time), if people want this.

---

<div class="post-metadata">

**Author:** ![John\_Carlisle](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/john_carlisle/32/21156_2.png) [@John\_Carlisle](https://forum.babylonjs.com/u/John_Carlisle)\
**Post date:** [January 13, 2022, 10:55am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/8 "2022-01-13T10:55:03Z")

</div>

Hi everyone, i really appreciate all the replies. Ive had a go at using all the suggested ways to solve it (just seem to be having some challenges with the transpile issue; not being able to resolve or import babylon-loaders and recieving errors for next/dynamic options/requiring object literal). If anyone comes across a really basic step by step way to do it that is guarenteed to work(including what to install, preferrably no need to modify config files, and then exactly what code to paste in each nextjs page), that would be so greatly appreciated. Thanks again for all the help so far

---

<div class="post-metadata">

**Author:** ![ecoin](https://avatars.discourse-cdn.com/v4/letter/e/8e7dd6/32.png) [@ecoin](https://forum.babylonjs.com/u/ecoin)\
**Post date:** [January 13, 2022, 3:33pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/9 "2022-01-13T15:33:42Z")

</div>

> [@John\_Carlisle](#):
>
> not being able to resolve or import babylon-loaders

That means Next.js tries to import Babylon in Node.js environment, or you have errors in your setup not related to Babylon.

My code above was copy pasted from existing working project, however, right now I do not have time to setup a template repo to share with you.

You can try my **next.config.js** :

```auto
// @Note: next.config.js gets loaded once at the start, then babel.config.js (loaded repeatedly)
const {withPlugins, optional} = require('next-compose-plugins')
const {PHASE_PRODUCTION_SERVER} = require('next/constants')
let {modulesToTranspile} = require('./config')
modulesToTranspile = modulesToTranspile.filter(v => v !== '@babylonjs')
const clientEnvs = {}
for (const key in process.env) {
  if (key.indexOf('REACT_APP_') === 0) clientEnvs[key] = process.env[key]
}
/** Tested with Next.js v12.22.1 Webpack v4.4.1 */
module.exports = withPlugins(
  /** IMPORTANT: the order of plugins matter! */
  [
    /* Must be the first plugin (to work with decorator {legacy: true}) */
    [optional(() => require('@next/bundle-analyzer')({
      enabled: process.env.ANALYZE === 'true',
    })({})), {}, ['!', PHASE_PRODUCTION_SERVER]],

    /* Webpack configuration must go here */
    [optional(() => require('next-transpile-modules')(modulesToTranspile)), {
      /**
       * The webpack function is executed twice, once for the server and once for the client.
       * @see https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config
       */
      webpack: (config, {buildId, dev, isServer, defaultLoaders, webpack}) => {
        // Comment this out if you do not use GraphQL
        config.module.rules.push({
          test: /\.(graphql|gql)$/,
          loader: 'graphql-tag/loader', // works with fragment #import
        })
        return config
      },
    }, ['!', PHASE_PRODUCTION_SERVER]],
  ],

  /** next.config.js configuration */
  {
    // @note: 'next-compose-plugins' has a bug and does not call webpack(config) here
    // @see: https://github.com/cyrilwanner/next-compose-plugins/issues/41
    /**
     * For Security reasons, Next.js does not export process.env to client side.
     * Manually export all envs starting with `REACT_APP_*` to sync with CRA best practices
     */
    publicRuntimeConfig: {
      NODE_ENV: process.env.NODE_ENV,
      ...clientEnvs,
    },
    /**
     * @see: https://nextjs.org/docs/advanced-features/i18n-routing
     */
    i18n: {
      locales: ['en', 'fr', 'ru'],
      defaultLocale: 'en',
    },
    /**
     * @see: https://nextjs.org/docs/api-reference/next.config.js/rewrites
     */
    async rewrites () {
      return {
        // These rewrites are checked after both pages/public files
        // and dynamic routes are checked
        fallback: [
          { // Rewrite everything else to use `pages/spa.js` Single Page Application
            source: '/:path*',
            destination: '/spa',
          },
        ]
      }
    },
  }
)

```

**babel.config.js**

```auto
const {modulesToTranspile} = require('./config')
module.exports = (api) => {
  api.cache(false) // set cache as true/false

  return {
    plugins: [
      [
        '@babel/plugin-proposal-decorators',
        {
          'legacy': true
        }
      ],
      'lodash',
    ],
    presets: [
      'next/babel'
    ],
    ignore: [
      // this duplicated declaration from next.config.js produces slightly smaller bundle
      new RegExp(`node_modules/(?!(${modulesToTranspile.join('|')})/)`)
    ],
  }
}

```

c **onfig.js**

```auto
module.exports = {
  modulesToTranspile: [
    'validator', // importing ES6 code for tree shaking
    /**
     * frontend only
     * next@10.2.3 with next-transpile-modules@7.3.0 must have this disabled
     * use dynamic import instead to avoid rendering Babylon server side and slowing down dev
     */
    '@babylonjs', // required for Jest test
  ]
}

```

package.json

```auto
  "dependencies": {
    "next": "10.2.3"
  },
  "peerDependencies": {
    "react": "x",
  },
  "devDependencies": {
    "@babel/plugin-proposal-decorators": "^7.10.1",
    "@next/bundle-analyzer": "10.2.3",
    "next-compose-plugins": "^2.2.1",
    "next-transpile-modules": "7.3.0",
    "@testing-library/jest-dom": "^5.11.0",
    "@testing-library/react": "^10.4.3",
    "babel-jest": "^26.1.0",
    "babel-plugin-import-graphql": "^2.8.1",
    "babel-plugin-lodash": "^3.3.4",
    "concurrently": "^5.2.0",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^26.1.0",
    "jest-transform-graphql": "^2.1.0",
    "madge": "^3.9.2",
    "react-test-renderer": "^16.13.1",
    "rimraf": "^3.0.2"
  }

```

---

<div class="post-metadata">

**Author:** ![RaananW](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/raananw/32/28955_2.png) [@RaananW](https://forum.babylonjs.com/u/RaananW)\
**Post date:** [January 14, 2022, 10:49am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/10 "2022-01-14T10:49:27Z")

</div>

> [@John\_Carlisle](#):
>
> not being able to resolve or import babylon-loaders

Just my two cents here, and not sure it will help in any way, but don’t use babylonjs-loaders, instead use the es version at @babylonjs/loaders . This might work a little better.

---

<div class="post-metadata">

**Author:** ![jeremy-coleman](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jeremy-coleman/32/15493_2.png) [@jeremy-coleman](https://forum.babylonjs.com/u/jeremy-coleman)\
**Post date:** [January 14, 2022, 5:12pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/11 "2022-01-14T17:12:51Z")

</div>

#### For nextjs v11 and below

because next is a cjs node server. If you use the esm version of babylon, you will just have to transpile it to cjs. Although, i think they added esm support in the latest version. They also added swc as the default compiler but will revert to babel if u have a babel config in your project.

The core issue is that next skips transpiling node modules, because practically all packages ship cjs and esm or umd. For packages that dont, like babylon, most people use the “next-transpile-modules” plugin which just tells next to transpile certain packages inside of node modules.

Here is an example  
.[next-babylonjs/next.config.js at master · Flux159/next-babylonjs · GitHub](https://github.com/Flux159/next-babylonjs/blob/master/next.config.js)  
  
  
@RaananW I was wrong, updated correction:

#### For nextjs v12 and above

I just confirmed with the example repo above you can remove next-transpile-modules with nextjs v12, using either babel or swc. So you can use `@babylon/core` and babel-plugin-glsl (glslify in a babel macro) . w00t.

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [February 11, 2022, 2:30pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/12 "2022-02-11T14:30:03Z")

</div>

Hi @John_Carlisle just checking in, how’s your project going? Can we help you in anything else? 🙂

---

<div class="post-metadata">

**Author:** ![John\_Carlisle](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/john_carlisle/32/21156_2.png) [@John\_Carlisle](https://forum.babylonjs.com/u/John_Carlisle)\
**Post date:** [February 12, 2022, 10:22am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/13 "2022-02-12T10:22:23Z")

</div>

Hi carolhmj thanks for checking in. Im still struggling to get babylon running on next js. Ive been continuing my project with just babylon, html and express server until i can solve how to get it running on next js(which is what i really want to be able to do). Any advice you have would be really appreciated. Thanks again John

---

<div class="post-metadata">

**Author:** ![ecoin](https://avatars.discourse-cdn.com/v4/letter/e/8e7dd6/32.png) [@ecoin](https://forum.babylonjs.com/u/ecoin)\
**Post date:** [February 12, 2022, 2:03pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/14 "2022-02-12T14:03:57Z")

</div>

> [@John\_Carlisle](#):
>
> how to get it running on next js

Here is the the [ready made template forum announcement](https://forum.babylonjs.com/t/babylon-next-js-setup-optimized-for-seo-load-speed-developer-experience/27412) - post questions here.  
Direct link to guide: [How to Setup Babylon + Next.js in Production Optimized for SEO & Speed](https://3designer.app/best/babylon-nextjs-setup)

---

<div class="post-metadata">

**Author:** ![John\_Carlisle](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/john_carlisle/32/21156_2.png) [@John\_Carlisle](https://forum.babylonjs.com/u/John_Carlisle)\
**Post date:** [April 13, 2022, 10:12am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/15 "2022-04-13T10:12:27Z")

</div>

Hi ecoin, im just comming back to this. Do you know if there is a simpler step by step set of instructions i can follow (the template is still a bit to advanced for me).

I am really keen to learn how to use babylon with next js

Thanks again John

---

<div class="post-metadata">

**Author:** ![ecoin](https://avatars.discourse-cdn.com/v4/letter/e/8e7dd6/32.png) [@ecoin](https://forum.babylonjs.com/u/ecoin)\
**Post date:** [April 13, 2022, 10:38am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/16 "2022-04-13T10:38:09Z")

</div>

> [@John\_Carlisle](#):
>
> step by step set of instructions

For the [this](https://github.com/ecoinomist/babylon-next) here are the step by step (I’m assuming you have Git installed on your Mac computer with terminal access:

```auto
git clone https://github.com/ecoinomist/babylon-next.git your-project-name
cd your-project-name
yarn
yarn dev

```

Then you can begin modifying Babylon scene in [this file](https://github.com/ecoinomist/babylon-next/blob/main/repos/client/views/SceneView.js).

```auto
cd repos/client/views
# open the SceneView.js to start editing

```

Does this answer your question?

---

<div class="post-metadata">

**Author:** ![John\_Carlisle](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/john_carlisle/32/21156_2.png) [@John\_Carlisle](https://forum.babylonjs.com/u/John_Carlisle)\
**Post date:** [April 13, 2022, 11:39am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/17 "2022-04-13T11:39:15Z")

</div>

that is almost perfect thanks ecoin. The final little thing i am just trying to solve is that when i cd into the project directory and type npm run dev i get an error message(see below). Can you see what i might need to do differently to run it thanks again for all your help John

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/7/b/7b3b52322eca4574ca824e79b94c385cc642d30a.png)

---

<div class="post-metadata">

**Author:** ![ecoin](https://avatars.discourse-cdn.com/v4/letter/e/8e7dd6/32.png) [@ecoin](https://forum.babylonjs.com/u/ecoin)\
**Post date:** [April 13, 2022, 12:44pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/18 "2022-04-13T12:44:09Z")

</div>

You need to install yarn package manager first:

1. Install [brew](https://brew.sh/)
2. Install yarn

```auto
brew install yarn

```

Please check out this comment for full instructions: [Babylon + Next.js Setup Optimized for SEO, Load Speed & Developer Experience - #24 by ecoin](https://forum.babylonjs.com/t/babylon-next-js-setup-optimized-for-seo-load-speed-developer-experience/27412/24)

---

<div class="post-metadata">

**Author:** ![brianzinn](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/brianzinn/32/28013_2.png) [@brianzinn](https://forum.babylonjs.com/u/brianzinn)\
**Post date:** [April 14, 2022, 10:54pm UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/19 "2022-04-14T22:54:13Z")

</div>

I think without yarn at least newer versions of 7 and higher of NPM:  
‘npm run dev -w web’

-w means to run in that workspace

---

<div class="post-metadata">

**Author:** ![John\_Carlisle](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/john_carlisle/32/21156_2.png) [@John\_Carlisle](https://forum.babylonjs.com/u/John_Carlisle)\
**Post date:** [April 15, 2022, 9:01am UTC](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665/20 "2022-04-15T09:01:27Z")

</div>

not having much luck (see errors below)

I wish using babylon with next was as simple as just importing a static file/route

Thx

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/a/c/ac3d1381409967dc6936491d30372994922de9dd.png)

[Next page](https://forum.babylonjs.com/t/how-to-use-babylon-with-next-js/26665.md?page=2)
