---
title: jlabx
description: Launch JupyterLab with extensions — without touching your project's dependencies.
---

import { Aside } from "@astrojs/starlight/components";

Launch JupyterLab with your favorite extensions — without adding them to your project's `pyproject.toml` or `pixi.toml`. Works with both **uv** and **pixi** projects out of the box.

## Install

```bash
uv tool install jlabx
```

## Usage

In a project with a `pyproject.toml` or `pixi.toml`, just run:

```bash
jlabx
```

jlabx auto-detects your environment and launches JupyterLab with collaboration, LSP, and your configured extensions — without adding them to your project's dependencies.

Open a notebook with auto-detected dependencies (creates the file if it doesn't exist):

```bash
jlabx analysis.ipynb
```

If the notebook has no [PEP 723](https://packaging.python.org/en/latest/specifications/inline-script-metadata/) metadata, jlabx scans `import` statements, maps them to PyPI packages (`sklearn` → `scikit-learn`, `PIL` → `Pillow`, etc.), and passes them as `--with` args — so the notebook just works.

```bash
# Persist auto-detected deps into the notebook as PEP 723 metadata
jlabx analysis.ipynb --init-deps

# Force uv even in a pixi project
jlabx --uv

# Skip user extensions, core only
jlabx --no-extras

# Manage your global UI extensions
jlabx add jupyterlab-vim
jlabx remove jupyterlab-git
jlabx list
```

See [Usage](/jlabx/usage/) for full details.

## How it works

jlabx manages extensions separately from your project and injects them at launch time. It auto-detects your environment:

- **Pixi project** (`pixi.toml`) — `pixi run jupyter-lab`
- **Python project** (`pyproject.toml`) — `uv run --with <extensions> jupyter-lab`
- **Standalone** — `uvx --from jupyterlab --with <extensions> jupyter-lab`
- **Single notebook** (`.ipynb` arg) — delegates to [juv](https://github.com/manzt/juv) with extensions as `--with` args

See [Environments](/jlabx/environments/) for details.

## Notebook mode

When you pass a `.ipynb` file, jlabx delegates to [juv](https://github.com/manzt/juv) for per-notebook dependency management:

- **Has PEP 723 metadata** — juv resolves the notebook's own deps, jlabx adds UI extensions on top
- **No metadata** — jlabx scans `import` statements, maps them to PyPI packages, and passes them as `--with` args
- **`--init-deps`** — writes detected deps into the notebook as a PEP 723 metadata cell via `juv init` + `juv add`

juv is fetched automatically via `uvx` — no separate install needed.

## Extensions

Every launch includes these **core extensions**:

- `jupyterlab` — JupyterLab itself
- `jupyter-collaboration` — real-time collaboration
- `jupyter-lsp` + `python-lsp-server` — language server support

On top of that, jlabx loads **user extensions** from `~/.config/jlabx/config.toml`. The defaults are `jupyterlab-vim`, `jupyterlab-myst`, and `jupyterlab-git` — change them with `jlabx add` and `jlabx remove`. See [Configuration](/jlabx/config/) for details.

<Aside type="tip">
  Use `jlabx --no-extras` to skip user extensions and launch with only the core set.
</Aside>

## Why?

You're working in a repo with a `pyproject.toml` or `pixi.toml` — maybe it's a library, a data pipeline, or a research project. You want JupyterLab with vim bindings, collaboration, LSP, and other extensions. But adding `jupyterlab` and all those extras to your project dependencies would bloat things up and create conflicts.

jlabx keeps your project clean by managing JupyterLab extensions in a separate config, then injecting them at launch time. It auto-detects whether you're in a **pixi** or **uv** project and does the right thing.
