Skip to content

Commit 9d34a6a

Browse files
docs: DOC-632-js plugins (#7505)
1 parent d36277e commit 9d34a6a

4 files changed

Lines changed: 211 additions & 0 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
title: Create a JavaScript plugin
3+
---
4+
5+
JS plugins are registered using Python packages regardless of which query language you use. See [Create a JavaScript plugin](https://deephaven.io/core/docs/how-to-guides/create-js-plugins/) in the Python documentation for the full guide.
6+
7+
## Related documentation
8+
9+
- [Install and use plugins](./install-use-plugins.md)
10+
- [deephaven-plugins repository](https://github.com/deephaven/deephaven-plugins)
11+
- [JsPlugin Python class](https://github.com/deephaven/deephaven-plugin/blob/main/src/deephaven/plugin/js.py)
12+
- [JsPlugin Java interface](https://github.com/deephaven/deephaven-core/blob/main/plugin/src/main/java/io/deephaven/plugin/js/JsPlugin.java)

docs/groovy/sidebar.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,10 @@
10941094
{
10951095
"label": "Create your own plugin",
10961096
"path": "how-to-guides/create-plugins.md"
1097+
},
1098+
{
1099+
"label": "Create a JavaScript plugin",
1100+
"path": "how-to-guides/create-js-plugins.md"
10971101
}
10981102
]
10991103
},
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
---
2+
title: Create a JavaScript plugin
3+
---
4+
5+
This guide covers creating JavaScript (JS) plugins that extend the Deephaven web UI with custom React components. For plugins that extend the Python client API with custom RPC methods, see [Create your own plugin](./create-plugins.md).
6+
7+
JS plugins serve static JavaScript, CSS, and other assets from the Deephaven server. The web UI automatically loads registered plugins on startup.
8+
9+
## Prerequisites
10+
11+
Before creating a JS plugin, you should be familiar with:
12+
13+
- [React](https://react.dev/) and TypeScript/JavaScript
14+
- [npm](https://www.npmjs.com/) package management
15+
- Python packaging basics
16+
17+
## When to create a JS plugin
18+
19+
Create a JS plugin when you need to:
20+
21+
- Add custom visualization components to the Deephaven web UI.
22+
- Integrate third-party charting or UI libraries (D3, Chart.js, etc.).
23+
- Create reusable UI components that can be shared across projects.
24+
- Build components that require complex client-side interactivity.
25+
26+
If you only need custom UI for a single project without sharing, consider using [`deephaven.ui`](./deephaven-ui.md) components directly.
27+
28+
## Quick start with cookiecutter
29+
30+
The easiest way to create a JS plugin is with the [cookiecutter](https://cookiecutter.readthedocs.io/) templates from the [deephaven-plugins](https://github.com/deephaven/deephaven-plugins) repository:
31+
32+
```bash
33+
pip install cookiecutter
34+
cookiecutter gh:deephaven/deephaven-plugins --directory="templates/element"
35+
```
36+
37+
This creates a complete project with Python registration, React scaffolding, and build configuration.
38+
39+
## Plugin architecture
40+
41+
A JS plugin consists of two parts:
42+
43+
1. **Python package**: Registers the plugin with the Deephaven server and specifies where the JS assets are located.
44+
2. **JavaScript bundle**: Contains the React components and any other client-side code.
45+
46+
### Python registration
47+
48+
The Python side uses [`deephaven.plugin.js.JsPlugin`](https://github.com/deephaven/deephaven-plugin/blob/main/src/deephaven/plugin/js.py) to register the plugin. This class tells the server where to find the JS assets:
49+
50+
```python skip-test
51+
from deephaven.plugin.js import JsPlugin
52+
from deephaven.plugin import Registration, Callback
53+
import pathlib
54+
55+
56+
class MyPluginJsPlugin(JsPlugin):
57+
@property
58+
def name(self) -> str:
59+
# Contents served at js-plugins/{name}/
60+
return "@my-org/my-plugin"
61+
62+
@property
63+
def version(self) -> str:
64+
return "0.1.0"
65+
66+
@property
67+
def main(self) -> str:
68+
# Path to main JS file, relative to path()
69+
return "dist/index.js"
70+
71+
def path(self) -> pathlib.Path:
72+
# Directory containing built JS assets
73+
return pathlib.Path(__file__).parent / "js"
74+
75+
76+
class MyPluginRegistration(Registration):
77+
@classmethod
78+
def register_into(cls, callback: Callback) -> None:
79+
callback.register(MyPluginJsPlugin())
80+
```
81+
82+
The `pyproject.toml` must register the plugin as an entry point:
83+
84+
```toml
85+
[build-system]
86+
requires = ["setuptools"]
87+
build-backend = "setuptools.build_meta"
88+
89+
[project]
90+
name = "my-plugin"
91+
version = "0.1.0"
92+
dependencies = ["deephaven-plugin>=0.6.0"]
93+
94+
[project.entry-points."deephaven.plugin"]
95+
registration_cls = "my_plugin:MyPluginRegistration"
96+
```
97+
98+
### JavaScript structure
99+
100+
The JS plugin must export modules that the Deephaven web UI can load. For element plugins extending `deephaven.ui`, the main export is typically a React component.
101+
102+
Key requirements for JS plugins:
103+
104+
- Use a scoped package name like `@your-org/your-plugin` (official Deephaven plugins use `@deephaven/js-plugin-<name>`).
105+
- Export as a CommonJS (CJS) bundle.
106+
- Externalize shared dependencies: `react`, `react-dom`, `redux`, `react-redux`, and `@deephaven/*` packages.
107+
108+
Example `package.json`:
109+
110+
```json
111+
{
112+
"name": "@my-org/my-plugin",
113+
"version": "0.1.0",
114+
"type": "module",
115+
"scripts": {
116+
"build": "vite build"
117+
},
118+
"devDependencies": {
119+
"@vitejs/plugin-react": "^4.0.0",
120+
"typescript": "^5.0.0",
121+
"vite": "^5.0.0"
122+
},
123+
"peerDependencies": {
124+
"react": "^18.2.0",
125+
"react-dom": "^18.2.0"
126+
}
127+
}
128+
```
129+
130+
Example `vite.config.ts`:
131+
132+
```typescript
133+
import react from "@vitejs/plugin-react";
134+
import { defineConfig } from "vite";
135+
136+
export default defineConfig({
137+
plugins: [react()],
138+
build: {
139+
lib: {
140+
entry: "src/index.tsx",
141+
formats: ["cjs"],
142+
fileName: () => "index.js",
143+
},
144+
rollupOptions: {
145+
external: [
146+
"react",
147+
"react-dom",
148+
"redux",
149+
"react-redux",
150+
/@deephaven\/.*/,
151+
],
152+
},
153+
outDir: "dist",
154+
},
155+
});
156+
```
157+
158+
## Development workflow
159+
160+
1. Build the JS: `npm install && npm run build`.
161+
2. Install the Python package: `pip install -e ./path/to/my-plugin`.
162+
3. Start Deephaven - the plugin loads automatically.
163+
4. Iterate: edit JS code, rebuild, refresh the web UI.
164+
165+
For faster iteration with hot module replacement, see the [deephaven-plugins development documentation](https://github.com/deephaven/deephaven-plugins#development).
166+
167+
## Complete examples
168+
169+
The best way to learn JS plugin development is to study existing plugins. The [deephaven-plugins](https://github.com/deephaven/deephaven-plugins) repository contains production-ready examples:
170+
171+
- [`plotly-express`](https://github.com/deephaven/deephaven-plugins/tree/main/plugins/plotly-express): Plotly visualization integration.
172+
- [`matplotlib`](https://github.com/deephaven/deephaven-plugins/tree/main/plugins/matplotlib): Matplotlib figure support.
173+
- [`json`](https://github.com/deephaven/deephaven-plugins/tree/main/plugins/json): JSON viewer component.
174+
- [`ui`](https://github.com/deephaven/deephaven-plugins/tree/main/plugins/ui): The deephaven.ui framework itself.
175+
176+
Each plugin demonstrates:
177+
178+
- Python registration with `JsPlugin`.
179+
- React component structure.
180+
- Data flow between Python and JavaScript.
181+
- Build configuration with Vite.
182+
183+
For a guided setup, use the cookiecutter templates which generate a complete working project structure.
184+
185+
## Related documentation
186+
187+
- [Install and use plugins](./install-use-plugins.md)
188+
- [Create your own bidirectional Python plugins](./create-plugins.md)
189+
- [deephaven.ui](./deephaven-ui.md)
190+
- [deephaven-plugins repository](https://github.com/deephaven/deephaven-plugins)
191+
- [JsPlugin Python class](https://github.com/deephaven/deephaven-plugin/blob/main/src/deephaven/plugin/js.py)

docs/python/sidebar.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,10 @@
897897
{
898898
"label": "Create your own plugin",
899899
"path": "how-to-guides/create-plugins.md"
900+
},
901+
{
902+
"label": "Create a JavaScript plugin",
903+
"path": "how-to-guides/create-js-plugins.md"
900904
}
901905
]
902906
},

0 commit comments

Comments
 (0)