# Extension templates and TLJH

**URL:** <https://discourse.jupyter.org/t/extension-templates-and-tljh/19884>\
**Category:** extensions\
**Tags:** jupyterhub\
**Created:** [June 13, 2023, 2:36pm UTC](https://discourse.jupyter.org/t/extension-templates-and-tljh/19884 "2023-06-13T14:36:25Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jdmansour](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jdmansour/32/6427_2.png) [@jdmansour](https://discourse.jupyter.org/u/jdmansour)\
**Post date:** [June 13, 2023, 2:36pm UTC](https://discourse.jupyter.org/t/extension-templates-and-tljh/19884/1 "2023-06-13T14:36:25Z")

</div>

Hi, I would like to make a JupyterLab extension, but it seems the official templates have version conflicts with TLJH.

[extension-template](https://github.com/jupyterlab/extension-template) requires JupyterLab 4.0, but TLJH is currently on 3.6.4. So no problem, I’ll use [extension-cookiecutter-ts](https://github.com/jupyterlab/extension-cookiecutter-ts) using the 3.0 tag. That gets me further (the Python packages no longer conflict), but it still fails, because some dependency down the line requires Node v16, but TLJH comes with Node v14.

> **Error message when calling pip**
>
> ````plaintext
> # export PATH="/opt/tljh/user/bin:$PATH
> # hash -r
> # pip install -e ".[test]"
> [...]
> Building wheels for collected packages: gradingtool
> Building editable for gradingtool (pyproject.toml) ... error
> ERROR: Command errored out with exit status 1:
> command: /opt/tljh/user/bin/python3.9 /opt/tljh/user/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py build_editable /tmp/tmpoeb659zb
> cwd: /home/cloud/src/gradingtool
> Complete output (46 lines):
> INFO:hatch_jupyter_builder.utils:Running jupyter-builder
> INFO:hatch_jupyter_builder.utils:Building with hatch_jupyter_builder.npm_builder
> INFO:hatch_jupyter_builder.utils:With kwargs: {'build_cmd': 'install:extension', 'npm': ['jlpm'], 'source_dir': 'src', 'build_dir': 'gradingtool/labextension'}
> INFO:hatch_jupyter_builder.utils:Installing build dependencies with npm. This may take a while...
> INFO:hatch_jupyter_builder.utils:> /tmp/pip-build-env-4szlgmah/overlay/bin/jlpm install
> yarn install v1.21.1
> info No lockfile found.
> [1/4] Resolving packages...
> warning @jupyterlab/application > @jupyterlab/ui-components > @blueprintjs/core > popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
> warning @jupyterlab/application > @jupyterlab/ui-components > @blueprintjs/core > react-popper > popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the leg
> acy v1
> warning @jupyterlab/builder > terser-webpack-plugin > cacache > @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
> warning @jupyterlab/testutils > jest-junit > uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See h
> ttps://v8.dev/blog/math-random for details.
> warning @jupyterlab/testutils > jest > @jest/core > jest-haste-map > sane@4.1.0: some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added
> warning @jupyterlab/testutils > jest > @jest/core > jest-config > jest-environment-jsdom > jsdom > w3c-hr-time@1.0.2: Use your platform's native performance.now() and performance.timeOrigin.
> warning @jupyterlab/testutils > jest > @jest/core > jest-haste-map > sane > micromatch > snapdragon > source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
> warning @jupyterlab/testutils > jest > @jest/core > jest-haste-map > sane > micromatch > snapdragon > source-map-resolve > resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
> warning @jupyterlab/testutils > jest > @jest/core > jest-haste-map > sane > micromatch > snapdragon > source-map-resolve > source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
> warning @jupyterlab/testutils > jest > @jest/core > jest-haste-map > sane > micromatch > snapdragon > source-map-resolve > urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
> [2/4] Fetching packages...
> warning @blueprintjs/core@3.54.0: Invalid bin entry for "upgrade-blueprint-2.0.0-rename" (in "@blueprintjs/core").
> warning @blueprintjs/core@3.54.0: Invalid bin entry for "upgrade-blueprint-3.0.0-rename" (in "@blueprintjs/core").
> error lib0@0.2.78: The engine "node" is incompatible with this module. Expected version ">=16". Got "14.17.4"
> error Found incompatible module.
> info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
> Traceback (most recent call last):
> File "/opt/tljh/user/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 349, in <module>
> main()
> File "/opt/tljh/user/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 331, in main
> json_out['return_val'] = hook(**hook_input['kwargs'])
> File "/opt/tljh/user/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 270, in build_editable
> return hook(wheel_directory, config_settings, metadata_directory)
> File "/tmp/pip-build-env-4szlgmah/overlay/lib/python3.9/site-packages/hatchling/build.py", line 78, in build_editable
> return os.path.basename(next(builder.build(wheel_directory, ['editable'])))
> File "/tmp/pip-build-env-4szlgmah/overlay/lib/python3.9/site-packages/hatchling/builders/plugin/interface.py", line 150, in build
> build_hook.initialize(version, build_data)
> File "/tmp/pip-build-env-4szlgmah/normal/lib/python3.9/site-packages/hatch_jupyter_builder/plugin.py", line 87, in initialize
> raise e
> File "/tmp/pip-build-env-4szlgmah/normal/lib/python3.9/site-packages/hatch_jupyter_builder/plugin.py", line 82, in initialize
> build_func(self.target_name, version, **build_kwargs)
> File "/tmp/pip-build-env-4szlgmah/normal/lib/python3.9/site-packages/hatch_jupyter_builder/utils.py", line 113, in npm_builder
> run([*npm_cmd, "install"], cwd=str(abs_path))
> File "/tmp/pip-build-env-4szlgmah/normal/lib/python3.9/site-packages/hatch_jupyter_builder/utils.py", line 229, in run
> return subprocess.check_call(cmd, **kwargs)
> File "/opt/tljh/user/lib/python3.9/subprocess.py", line 373, in check_call
> raise CalledProcessError(retcode, cmd)
> subprocess.CalledProcessError: Command '['/tmp/pip-build-env-4szlgmah/overlay/bin/jlpm', 'install']' returned non-zero exit status 1.
> ----------------------------------------
> ERROR: Failed building editable for gradingtool
> Failed to build gradingtool
> ERROR: Could not build wheels for gradingtool, which is required to install pyproject.toml-based projects```
> 
> ````

I’m rather hesitant to install an additional version of Node because I don’t know which one will be picked up by which tool.

Currently I’m not sure if this is a bug in the template, or if I’m doing it wrong 🙂 . Is there a currently blessed way to create an extension that works with TLJH (and preferably Z2JH and other setups of course)? Or is the best way to just start with a random extension and modify it?

---

<div class="post-metadata">

**Author:** ![jdmansour](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jdmansour/32/6427_2.png) [@jdmansour](https://discourse.jupyter.org/u/jdmansour)\
**Post date:** [June 14, 2023, 10:10am UTC](https://discourse.jupyter.org/t/extension-templates-and-tljh/19884/2 "2023-06-14T10:10:22Z")

</div>

I think I found a solution. It seems node.js has been removed from the TLJH distribution, but my ancient installation still had it lying around in `/opt/tljh/user/bin`. I removed `/opt/tljh/user/bin/{node,npm,npx}`, installed a more recent node from the official website globally, and it works!

The takeaway for me is to probably nuke the server every now and then and set it up cleanly 🙂 . It’s a good practice to use something like ansible and to be able to do that anyway.

(I also just realized that JupyterLab 4.0 only came out a couple of days ago, so no wonder it’s not in TLJH yet!)
