Surface plugins

Surfaces are Lit web components that query your local shenas database via Arrow IPC and render charts, tables, timelines — anything visual. They ship as a standard Python wheel, just like source plugins.

How surfaces work

Data access The surface component queries a local Arrow IPC endpoint that shenas exposes. All queries run against your local DuckDB — data never leaves your device.
Component model Each surface is a Lit custom element. The element registers itself via a shenas.surfaces entry point. shenas loads it into the UI shell.
Packaging A surface plugin is a Python package that includes both the Python entry point and the compiled JS component. Build with uv build; install with shenasctl source add --local.
Rendering Components control their own layout and charting library. Use any JS charting library — Observable Plot, Chart.js, D3 — bundled into the wheel.

Building a surface

1

Scaffold the component

Create a Lit custom element that extends LitElement. The component's connectedCallback fires an Arrow IPC query to fetch data from the local shenas database.

2

Declare the entry point

In pyproject.toml, add a shenas.surfaces entry point pointing at a Python class that returns the component name, title, and bundled JS path.

3

Bundle and package

Bundle the Lit component with esbuild or Vite, then include the bundle in the Python package's data files. Build the wheel with uv build.

4

Install and use

Install the surface wheel with shenasctl source add --local ./dist/<wheel>. The surface appears in the UI on the next page load.

Working surface examples are in shenas-org/shenas under plugins/surfaces/.