Thank you for your interest in contributing to the Splunk Custom Visualizations project. This guide covers everything you need to get started.
- Node.js (v16+) and npm
- Splunk Enterprise (for testing) — a local dev instance is recommended
- Familiarity with Canvas 2D and the Splunk Custom Visualization API
splunk-custom-visualizations/
├── build.sh # Build and package script
├── examples/ # Each subdirectory is a standalone Splunk viz app
│ └── {app_name}/
│ ├── default/
│ │ ├── app.conf
│ │ ├── savedsearches.conf
│ │ └── savedsearches.conf.spec
│ ├── metadata/
│ │ └── default.meta
│ └── appserver/static/visualizations/{app_name}/
│ ├── src/
│ │ └── visualization_source.js # Source (ES5 only)
│ ├── formatter.html # Settings UI
│ ├── visualization.css # Styles
│ ├── package.json
│ └── webpack.config.js
├── dist/ # Built tarballs (git-ignored)
└── screenshots/ # Screenshots used in documentation
-
Use the splunk-viz skill — run
/splunk-vizin Claude Code to scaffold a new visualization interactively. It generates all required files with the correct structure. -
Or copy an existing example — duplicate an
examples/{app_name}/directory, rename it, and update the identifiers inapp.conf,visualizations.conf, andpackage.json.
These rules are enforced by the project and must be followed in all contributions:
All code in visualization_source.js must use ES5 syntax. This is a Splunk framework requirement.
- Use
var, notconstorlet - Use
functiondeclarations, not arrow functions - Use
forloops, not.map()/.forEach()/.filter() - No template literals, destructuring, or spread operators
- Always handle HiDPI displays — scale the canvas by
window.devicePixelRatio - Guard against null context — check
ctxbefore drawing - Guard against zero-size canvas — bail early if width or height is 0
- Keep
visualization.cssbackground transparent by default
- Every setting in
formatter.htmlmust have a matching entry insavedsearches.conf.spec - JS default values must match formatter HTML defaults — Splunk does not send formatter defaults on first load
- Never read
configinformatData— do it inupdateView
Use the build script at the project root — do not run npm/webpack manually:
# Build all visualizations
./build.sh
# Build a specific one
./build.sh component_status_boardThis handles npm install, webpack bundling, and tarball packaging into dist/. The tarball excludes src/, node_modules/, and dev files automatically.
After building:
$SPLUNK_HOME/bin/splunk install app dist/{app_name}-{version}.tar.gz
$SPLUNK_HOME/bin/splunk restartOr copy the app directory directly for faster iteration during development:
cp -r examples/{app_name} $SPLUNK_HOME/etc/apps/
$SPLUNK_HOME/bin/splunk restartUse /_bump in the Splunk URL to reload static assets without a full restart when changing only JS/CSS.
The test harness (test-harness.html) uses Tailwind, compiled locally into shared/harness.css so it works without a CDN. The compiled CSS is committed so contributors and users can serve the harness directly with no build step.
If you change Tailwind classes in test-harness.html, rebuild and commit the CSS:
npm install # first time only
npm run build:css # writes shared/harness.cssnpm run watch:css rebuilds on save while iterating.
All top-level documentation (README.md, INSTRUCTIONS.md, CONTRIBUTING.md, EMBEDDING.md, TEST-HARNESS.md) must pass markdownlint-cli2. Viz-specific READMEs under examples/ and splunk_health/ are ignored.
Run the linter locally before opening a PR:
npx --yes markdownlint-cli2Rules and ignores live in .markdownlint-cli2.jsonc. The Lint workflow runs on every push and PR that touches a markdown file.
Common gotchas:
- Tables containing SPL pipes — escape literal
|inside code spans as\|(e.g.`\| rest /services/server/health`), otherwise the markdown parser treats the pipe as a new column (MD056). - Table separator row must match header style — use
| --- | --- | --- |with surrounding spaces, not|---|---|---|, to satisfy MD060.
- Fork the repository and create a feature branch
- Make your changes following the rules above
- Test in Splunk — verify the visualization renders correctly in both light and dark themes
- Run
./build.sh {app_name}to confirm the build succeeds - Run
npx --yes markdownlint-cli2if you touched any top-level.mdfiles - Open a pull request with:
- A description of what the visualization does
- A screenshot showing it in action
- The SPL query used for testing
By contributing, you agree that your contributions will be licensed under the Apache License 2.0.