A local-first satellite imagery composer for public STAC items.
Source Code · Installation · Configuration · License
Dionysus is a browser-based workspace for loading public satellite imagery from STAC item URLs, rendering those assets through TiTiler, and comparing scenes on an interactive map.
The current v1 release is focused on local Docker usage. A hosted GitHub Pages demo is planned, but not enabled yet.
- Load comma-separated public STAC item URLs.
- Sort scenes by acquisition date.
- Render one active scene at a time.
- Inspect scene metadata, constellation/platform, band count, and footprint area.
- Render single-band assets with TiTiler statistics-based contrast.
- Compute TiTiler band expressions and apply alphabetically sorted matplotlib colormaps.
- Compare two scenes or render configurations with swipe mode.
- Inspect raster histograms for the active render, including configurable histogram bin counts.
- Auto-switch the Inspector between left and right swipe scenes based on cursor position, while pausing that behavior when the cursor is over the Inspector.
- Inspect TiTiler tile request health with the map diagnostics panel.
- Review STAC compatibility guidance for CORS, requester-pays assets, and signed asset catalogs.
- Share the current composer, render, swipe, map center, and zoom state with a copyable link.
- Configure a local or remote TiTiler endpoint from the UI.
- Use OpenStreetMap or a custom XYZ basemap URL.
Dionysus is a client-side React application. It does not run an application backend of its own.
STAC Item URL(s)
-> browser fetches and parses STAC metadata
-> Dionysus extracts assets, dates, bands, geometry, and area
-> TiTiler creates statistics and TileJSON responses
-> MapLibre renders raster tiles on the map
-> tile diagnostics records TiTiler /tiles request status and timing
For local Docker usage, docker compose starts:
- the Vite React frontend
- a local TiTiler container
The frontend defaults to the local TiTiler endpoint in Docker:
http://localhost:8000
User preferences such as TiTiler endpoint, basemap, custom XYZ URL, and area unit are stored in browser local storage. Composer state is encoded in the URL so a configured scene can be shared.
| Area | Tools |
|---|---|
| Frontend | React, Vite, TypeScript |
| Routing and data | TanStack Router, TanStack Query, Axios |
| UI | Radix Themes, Radix Icons |
| Mapping | MapLibre GL, react-map-gl, deck.gl |
| Geospatial | TiTiler, STAC, Turf.js |
| Tooling | pnpm, Biome, Prettier, Docker Compose |
This is the recommended v1 workflow.
git clone https://github.com/neelduttahere/Dionysus.git
cd Dionysus
docker compose up --buildOpen the app:
http://localhost:5173
Running services:
| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| TiTiler | http://localhost:8000 |
Use this if TiTiler is already running somewhere else.
git clone https://github.com/neelduttahere/Dionysus.git
cd Dionysus
pnpm install
pnpm devOpen:
http://localhost:5173
The default non-Docker TiTiler endpoint is:
https://titiler.xyz
To change it before startup:
cp .env.example .envVITE_DEFAULT_TITILER_URL=http://localhost:8000
VITE_BASE_PATH=/
- Start Dionysus with Docker or
pnpm dev. - Open
http://localhost:5173. - Go to Composer.
- Paste one or more public STAC item URLs.
- Click
Load / Generate. - Use the timeline to move between loaded scenes.
- Choose a render mode:
DefaultSingle bandExpression
- Use
Swipemode to configure left and right scenes independently. - Open
Inspectorfrom the right-side map controls to review histogram statistics for the active render and adjust histogram bin count. - In
Swipemode, move the cursor across the split to let the Inspector follow the left or right scene automatically. - Open
Tile Diagnosticsfrom the top-right map control to inspect TiTiler tile requests.
Tile rendering can be slow when TiTiler is reading large Cloud Optimized GeoTIFFs, computing expression tiles, or fetching remote STAC assets. Dionysus includes a diagnostics panel for the raster tile requests made by the map.
The diagnostics panel shows:
- full TiTiler
/tilesrequest URLs - pending tile requests
- successful tile requests
- cancelled tile requests
- failed tile requests and error status
- request timing
Use Clear to reset the diagnostics list while testing a new scene, render
mode, expression, basemap position, or TiTiler endpoint.
Use these public Element 84 Sentinel-2 L2A STAC items around New York City to try Dionysus.
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2B_18TXK_20240921_0_L2A,
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2A_18TWK_20240913_0_L2A,
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2A_18TXK_20240913_0_L2A,
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2A_18TWL_20240913_0_L2A,
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2A_18TXL_20240913_0_L2A,
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2B_18TWK_20240911_0_L2A,
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2B_18TXK_20240908_0_L2A
Best first scene test:
https://earth-search.aws.element84.com/v1/collections/sentinel-2-l2a/items/S2B_18TXK_20240908_0_L2A
Sentinel-2 L2A expression examples using Element 84 asset names:
| Index | Purpose | Expression |
|---|---|---|
| NDVI | vegetation | (nir-red)/(nir+red) |
| NDWI | water | (green-nir)/(green+nir) |
| NDMI | moisture | (nir-swir16)/(nir+swir16) |
| NDBI-style | built-up areas | (swir16-nir)/(swir16+nir) |
| NBR | burn severity | (nir-swir22)/(nir+swir22) |
| Red-edge NDVI | vegetation variant | (nir08-red)/(nir08+red) |
Best first expression test:
(nir-red)/(nir+red)
Open the Settings panel and update TiTiler endpoint.
Examples:
http://localhost:8000
https://titiler.xyz
https://your-titiler.example.com
Use a local TiTiler endpoint for Docker-based local work. Use a remote endpoint only when it can access the STAC assets you are trying to render.
Open the Settings panel and choose:
OpenStreetMapCustom XYZ
Custom XYZ URLs must include {z}, {x}, and {y} placeholders.
https://tile.openstreetmap.org/{z}/{x}/{y}.png
https://your-tile-server.example.com/{z}/{x}/{y}.png
The Settings panel can display footprint area as:
- square kilometers
- square meters
- hectares
- acres
pnpm dev
pnpm check
pnpm build
pnpm format
pnpm previewDionysus can be deployed as a static GitHub Pages project site. Deployment is
coupled to GitHub Releases: publishing a release triggers the Pages workflow.
Pushes to master do not deploy automatically.
The Pages workflow builds with:
VITE_BASE_PATH=/Dionysus/
VITE_DEFAULT_TITILER_URL=https://titiler.xyz
The build also copies dist/index.html to dist/404.html so direct visits and
refreshes on routes such as /Dionysus/map/compose can boot the React app.
Unknown app routes render Dionysus' app-level not-found view.
Before publishing a release, run:
pnpm check
VITE_BASE_PATH=/Dionysus/ VITE_DEFAULT_TITILER_URL=https://titiler.xyz pnpm build
cp dist/index.html dist/404.htmlsrc/
api/ TiTiler and STAC request functions
components/ presentational UI components
config/ runtime defaults
containers/ route-aware orchestration components
hooks/ API, preference, theme, and composer hooks
routes/ TanStack Router route components
types/ shared TypeScript types
utils/ STAC, geometry, URL, and TiTiler utilities
Current v1 scope:
- local Docker workflow
- STAC item loading
- default visual rendering
- single-band rendering
- expression rendering
- tile diagnostics
- timeline navigation
- swipe compare
- custom TiTiler endpoint
- custom XYZ basemap
Planned later:
- GitHub Pages demo
- Force TCI asset mode
- RGB composite builder
- STAC provider presets
- additional map tools
See LICENSE.
Dionysus uses and builds on:
- TiTiler, by Development Seed
- STAC
- OpenStreetMap
- MapLibre GL
- deck.gl
- Turf.js
- React, Vite, TanStack, Radix, Axios, Biome, Prettier, and pnpm
Satellite imagery and metadata belong to their respective providers. Make sure the STAC items and tile services you use are public and allowed for your use case.
