npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

maplang

v0.1.0

Published

A diagramming language for maps — turn simple text into clean SVG maps.

Readme

MapL

A diagramming language for maps — turn simple text into clean SVG maps.

License: MIT Status


⚠️ Work in progress. MapL is in early design. The language spec and engine are still taking shape — APIs and syntax will change.

What is MapL?

MapL (Map Language) lets you describe a map in plain text and renders it to SVG — no GeoJSON wrangling, no GIS software, no coordinate math.

map

fill France color=#2c7fb8
fill Germany
fill Italy

point Paris
point Berlin
point [12.4964, 41.9028]

The goal: be to maps what Mermaid is to diagrams — simple to write, easy to embed in docs, and stable to render.

Data-driven thematic maps

Feed in values and let choropleth color regions automatically — a full thematic map with a title and legend, no per-region fill needed:

map
title "Western Europe — population (millions)"

data {
  France: 67.4
  Germany: 83.2
  Italy: 59.0
  Spain: 47.4
  Portugal: 10.3
}

choropleth scheme=YlGnBu steps=5 method=quantile
legend position=bottom-right title="Population (M)"

Data can also come from a file: load gdp.csv key=country value=gdp (CSV/JSON). Add theme dark for a dark background. An explicit fill X color=… always overrides the choropleth color for that region.

Proportional symbols and lines (SPEC v1.1)

Give a point a value= to size it by area (radius ∝ √value), tune the range with bubble, and connect places with line:

map
point Paris  value=11 label="Paris"
point London value=9  label="London"
bubble max=38 min=5
line London -> Paris curve=arc dashed color=#e11d48
legend position=bottom-left title="Metro pop (M)"

line endpoints use the same addressing as point (Name, "quoted", or [lng, lat]); curve=arc draws a purely visual upward curve (not a geodesic). A legend becomes a size legend when valued points are present.

One line can draw several segments (SPEC v2): a chain connects consecutive stops, a fan pairs one hub with a comma list on one side of the arrow — lists on both sides are an error (no cartesian products):

line London -> Paris -> Rome -> Athens curve=arc   # 3 segments
line Shanghai -> Tokyo, Seoul, Singapore           # hub fan-out
line Paris, Berlin -> London                       # fan-in

Give a fill a label= to name the region — the text lands at the shape's visual center (robust for concave shapes and archipelagos, where an area centroid would fall outside) with a halo for legibility:

map
fill France label="France"
fill Norway label="Norway"

Framing

map takes no region — the view is framed automatically around whatever you draw. Tune the breathing room with margins on the map line (CSS order: top right bottom left):

map margin=40              # 40px on every side
map margin=20,60           # 20 top/bottom, 60 left/right
map marginBottom=80        # override a single side

Variables (SPEC v2)

Use a vars block to keep repeated colors, numbers, names, and quoted strings in one place. Variables are expanded before parsing, so they work anywhere a normal value works:

vars {
  base: #c6dbef
  accent: #e6550d
  focus: France
  city: "New York"
}

map
fill $focus color=$accent
fill Germany color=$base
point $city label=$city

Each variable must be declared as name: value; an undefined $name reports the line where it is used. Values containing spaces must be quoted.

Style classes (SPEC v2)

Classes apply the same named style to several fills, points, or lines. Multiple classes are applied left-to-right, and explicit properties on the statement always win:

class land {
  color: #c6dbef
  stroke: #ffffff
  strokeWidth: 1.2
}
class highlight { color: #e6550d }

map
fill France class=land
fill Italy class="land highlight"
fill Spain class=land color=#74c476  # inline color wins

Line-only class properties are width, curve: straight|arc, and dashed: true|false. An unknown class reports the line where it is used.

Selectors: * and comma lists (SPEC v2)

One fill can target several regions — or every region of the basemap:

class muted { color: #e2e8f0 }

map
fill *                                  class=muted   # whole basemap, a base coat
fill Spain, Portugal                    color=#74c476
fill Belgium, Netherlands, Luxembourg   color=#6baed6

A comma list is exactly equivalent to writing one fill per name (unknown names report the same error). When statements touch the same region, the later one replaces the earlier one — so fill * works as a base coat that named fills and choropleth colors paint over. There is no prefix/fuzzy matching: list regions explicitly, or use * for the deterministic "everything".

point accepts comma lists too, freely mixing the three locator kinds; named places keep their own default labels:

point Paris, [118.8, 32.06], "南京南站" color=#e6550d size=5

point * is deliberately not supported ("every city" is not a meaningful map), and * never applies to line — but line has chain and fan forms, see the lines section above.

Design principles

  • Deterministic core — same DSL in, same SVG out. No I/O inside the engine.
  • Offline-first — built-in low-resolution data works without any network.
  • Pluggable everything — data sources, geocoding, and AI all sit behind interfaces, so the same engine can power both an offline build and optional online services.
  • Embeddable — a plain TypeScript/JS library that drops into the browser, Obsidian, VS Code, and Node without a separate binary.

Try it

npm install
npm run demo          # renders examples/europe.mapl -> examples/europe.svg

Or use the API / CLI:

import { renderMapL } from "maplang/node";
const svg = renderMapL("map\nfill France\npoint Paris");

For browser, editor, and custom-host integrations, import the I/O-free Core entry point and supply a DataProvider:

import { renderMapLToSvg, type DataProvider } from "maplang";

declare const dataProvider: DataProvider;
const svg = renderMapLToSvg("map\nfill France", dataProvider);

Advanced render backends can use the experimental scene IR instead of SVG:

import { compileMapL, renderSvg } from "maplang";

const scene = compileMapL("map\nfill France", dataProvider);
const svg = renderSvg(scene);
mapl examples/europe.mapl -o out.svg

Playground

A local browser playground with live preview and preset examples:

npm run playground        # serves http://localhost:8000 (live rebuild)

Or build a static bundle and open the page directly:

npm run playground:build  # writes playground/app.js
# then open playground/index.html in a browser

Project layout

src/
  core/       # Parser, AST, SVG renderer, colors; no host I/O
  node/       # Node data adapter and convenience API
  index.ts    # Public I/O-free Core entry (npm `maplang`)
  cli.ts      # Node CLI entry
playground/   # Browser editor; imports only the public Core API
data/         # Bundled TopoJSON and gazetteer
scripts/      # Data build pipeline

The Playground build aliases mapl to src/index.ts, so it bundles the same public Core API that consumers import after publication. Its development command watches this source entry; it does not reach into Core implementation modules directly.

Status

Pre-alpha. A minimal engine works end-to-end: a parser for map / fill / point plus data-driven data / load / choropleth / legend / title / theme (SPEC v1) and proportional symbols / line / bubble (SPEC v1.1), built-in geography (Natural Earth 1:50m map units, so France is the metropole and French Guiana is a separate region; rebuilt via npm run data:build), and an SVG renderer built on d3-geo + d3-scale. Syntax and APIs will still change.

License

MIT


Inspired by Mermaid and D2. MapL is an independent project and is not affiliated with either.