Notebooks Front End
by data-desk-eco
Use when editing docs/index.html, creating charts with Plot, adding SQL cells, loading data with FileAttachment, or building visualizations. Triggers on any editing of docs/index.html, Observable notebooks, or front-end visualization work.
Skill Details
Repository Files
1 file in this skill directory
name: notebooks-front-end description: Use when editing docs/index.html, creating charts with Plot, adding SQL cells, loading data with FileAttachment, or building visualizations. Triggers on any editing of docs/index.html, Observable notebooks, or front-end visualization work.
Observable Notebook Kit 2.0
Data Desk notebooks use Observable Notebook Kit 2.0 - standalone HTML pages with embedded JavaScript that compile to static sites.
Cell types
<!doctype html>
<notebook theme="midnight">
<title>Research title</title>
<!-- Markdown -->
<script id="header" type="text/markdown">
# Research title
</script>
<!-- JavaScript -->
<script id="analysis" type="module">
const data = await FileAttachment("../data/flows.csv").csv({typed: true});
display(Inputs.table(data));
</script>
<!-- SQL (queries DuckDB) -->
<script id="flows" output="flows" type="application/sql" database="../data/data.duckdb" hidden>
SELECT * FROM flows ORDER BY date DESC
</script>
<!-- Raw HTML -->
<script id="chart" type="text/html">
<div id="map" style="height: 500px;"></div>
</script>
</notebook>
Key points:
- Each
<script>has uniqueid - Cells are
type="module"by default (ES6 syntax) - Use
display()to render output (don't rely on return values) - Variables defined in one cell available to all others
- Use sentence case for all titles, headings, and chart titles (e.g., "Outages by country" not "Outages By Country")
- Keep the "last updated" date element - this is auto-populated from git and should not be removed
Loading data
FileAttachment API
Paths relative to notebook (docs/index.html):
- Data files in root
data/→ use../data/ - Assets in
docs/assets/→ useassets/ - Always
awaitFileAttachment calls
// CSV with type inference
const flows = await FileAttachment("../data/flows.csv").csv({typed: true});
// JSON
const projects = await FileAttachment("../data/projects.json").json();
// Parquet
const tracks = await FileAttachment("../data/tracks.parquet").parquet();
// Images
const img = await FileAttachment("assets/photo.jpg").url();
DuckDB / SQL cells (preferred for data)
Always prefer SQL cells with a DuckDB database over loading CSV/JSON directly. SQL cells query at build time, embedding results in HTML.
<script id="query" output="flows" type="application/sql" database="../data/data.duckdb" hidden>
SELECT * FROM flows WHERE year >= 2020
</script>
Attributes:
type="application/sql"- marks as SQL querydatabase="../data/data.duckdb"- path to database (relative to notebook)output="flows"- variable name for resultshidden- don't display output (optional)
Results available as JS variable:
display(html`<p>Found ${flows.length} flows</p>`);
DuckDB client (for complex/dynamic queries)
const db = DuckDBClient.of();
const summary = await db.query(`
SELECT year, count(*) as n, sum(volume_kt) as total
FROM flows GROUP BY year ORDER BY year
`);
display(Inputs.table(summary));
Visualization with Observable Plot
display(Plot.plot({
title: "Annual volumes by destination",
x: {label: "Year"},
y: {label: "Volume (Mt)", grid: true},
color: {legend: true},
marks: [
Plot.barY(data, {x: "year", y: "volume", fill: "region", tip: true}),
Plot.ruleY([0])
]
}));
Common marks: Plot.line(), Plot.barY(), Plot.areaY(), Plot.dot()
Built-in: automatic scales, tooltips with tip: true, responsive layout
Interactive inputs
// Toggle
const show_all = view(Inputs.toggle({label: "Show all columns"}));
// Search
const searched = view(Inputs.search(data));
// Table
display(Inputs.table(searched, {
rows: 25,
columns: show_all ? undefined : ["name", "date", "value"]
}));
// Slider, select, etc.
const threshold = view(Inputs.range([0, 100], {step: 1, value: 50}));
const country = view(Inputs.select(["UK", "Norway", "Sweden"]));
view() makes input reactive - other cells auto-update when value changes.
External libraries
Load via dynamic imports or CDN:
<!-- CSS -->
<script type="text/html">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet" />
</script>
<!-- JS library -->
<script type="module">
const script = document.createElement('script');
script.src = 'https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js';
script.onload = () => initMap();
document.head.appendChild(script);
</script>
Common patterns
Data aggregation
// Group by and sum
const annual = d3.rollup(flows, v => d3.sum(v, d => d.volume), d => d.year);
// Map to array
const data = Array.from(annual, ([year, volume]) => ({year, volume}))
.sort((a, b) => a.year - b.year);
Formatting
const formatDate = d3.utcFormat("%B %Y");
const formatNumber = d3.format(",.1f");
const formatCurrency = d3.format("$,.0f");
Inline calculations in markdown
// Calculate stats
const total = d3.sum(flows, d => d.volume);
const maxYear = d3.max(flows, d => d.year);
Reference in markdown:
<script type="text/markdown">
Analysis found ${total.toFixed(1)} Mt across ${flows.length} voyages,
peaking in ${maxYear}.
</script>
Geospatial (DuckDB Spatial)
<script type="application/sql" database="../data/flows.duckdb" output="ports">
SELECT port_name, ST_AsGeoJSON(geometry) as geojson, count(*) as visits
FROM port_visits GROUP BY port_name, geometry
</script>
Use in Mapbox/Leaflet:
ports.forEach(p => {
const coords = JSON.parse(p.geojson).coordinates;
new mapboxgl.Marker().setLngLat(coords).addTo(map);
});
Building and previewing
Before building or previewing, always run yarn first to install dependencies (including DuckDB). Without this, SQL queries will fail silently.
# Install dependencies (required for DuckDB queries)
yarn
# Preview with hot reload (auto-kills existing servers first)
make preview
# Build for production
make build
# Kill any orphaned preview servers
make kill
For Claude Code: Run preview in background, then kill when done:
make preview & # Start in background
# ... do work ...
make kill # Clean up when finished
Resources
- Observable Notebook Kit: https://observablehq.com/notebook-kit/
- Observable Plot: https://observablehq.com/plot/
- Observable Inputs: https://observablehq.com/notebook-kit/inputs
- DuckDB SQL: https://duckdb.org/docs/sql/introduction
Related Skills
Xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Analyzing Financial Statements
This skill calculates key financial ratios and metrics from financial statement data for investment analysis
Data Storytelling
Transform data into compelling narratives using visualization, context, and persuasive structure. Use when presenting analytics to stakeholders, creating data reports, or building executive presentations.
Team Composition Analysis
This skill should be used when the user asks to "plan team structure", "determine hiring needs", "design org chart", "calculate compensation", "plan equity allocation", or requests organizational design and headcount planning for a startup.
Startup Financial Modeling
This skill should be used when the user asks to "create financial projections", "build a financial model", "forecast revenue", "calculate burn rate", "estimate runway", "model cash flow", or requests 3-5 year financial planning for a startup.
Kpi Dashboard Design
Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data visualization layouts.
Dbt Transformation Patterns
Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.
Startup Metrics Framework
This skill should be used when the user asks about "key startup metrics", "SaaS metrics", "CAC and LTV", "unit economics", "burn multiple", "rule of 40", "marketplace metrics", or requests guidance on tracking and optimizing business performance metrics.
