A read-only web viewer for Elixir data structures
with syntax highlighting, code folding, and line numbers.
Built with vanilla TypeScript — powered by
lezer-elixir.
Accurate Elixir syntax coloring via lezer-elixir parser with a beautiful Tokyo Night theme.
Collapse and expand maps, lists, tuples, keyword lists, bitstrings, and multi-line strings.
Full-text search with match highlighting, case sensitivity toggle, and keyboard navigation.
Hide specific key-value pairs by name. Perfect for filtering out sensitive or noisy fields.
Click any value — atoms, strings, maps, lists — to copy it to your clipboard instantly.
Single ESM file with all deps bundled. Drop into Phoenix as a vendor file with LiveView hook support.
Try it out — fold, search, filter keys, and click values to copy.
# Download the latest standalone build from GitHub Releases:
# https://github.com/feng19/elixir-data-viewer/releases
#
# Grab `elixir-data-viewer.js` — single ESM file with all deps + CSS bundled
# Copy to your Phoenix project:
cp elixir-data-viewer.js your_phoenix_app/assets/vendor/
import ElixirDataViewer from "../vendor/elixir-data-viewer";
let Hooks = {};
Hooks.ElixirDataViewer = {
mounted() {
const viewer = new ElixirDataViewer(this.el);
viewer.setContent(this.el.dataset.content);
this.viewer = viewer;
},
updated() {
this.viewer.setContent(this.el.dataset.content);
},
};
<div id="data-viewer"
phx-hook="ElixirDataViewer"
data-content={inspect(@data, pretty: true)}>
</div>
npm install elixir-data-viewer
import { ElixirDataViewer } from "elixir-data-viewer";
import "elixir-data-viewer/style.css";
const container = document.getElementById("viewer")!;
const viewer = new ElixirDataViewer(container);
viewer.setContent(`%{name: "Alice", roles: [:admin, :user]}`);
<div class="edv-viewer">
<script type="text/elixir-data">
%{name: "Alice", age: 30, roles: [:admin, :user]}
</script>
</div>
<script type="module">
import { ElixirDataViewer } from "elixir-data-viewer";
import "elixir-data-viewer/style.css";
document.querySelectorAll(".edv-viewer").forEach((el) => {
const script = el.querySelector('script[type="text/elixir-data"]');
if (!script) return;
const data = script.textContent?.trim() ?? "";
script.remove();
const viewer = new ElixirDataViewer(el);
viewer.setContent(data);
});
</script>