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

metabase-iac

v0.3.0

Published

Infrastructure as Code for Metabase — manage collections, questions, dashboards as code

Readme

metabase-iac

Infrastructure as Code for Metabase. Manage collections, questions (SQL, MongoDB, structured), dashboards, and text cards as code.

Similar to how Grafana dashboards can be managed as JSON, metabase-iac lets you version-control your Metabase resources and apply changes through a CLI.

Install

pnpm add metabase-iac
# or
npm install metabase-iac

Quick start

# 1. Create a new directory for your Metabase instance
mkdir metabase-prod && cd metabase-prod
pnpm init && pnpm add metabase-iac

# 2. Configure credentials
cat > .env <<EOF
METABASE_URL=https://your-metabase.example.com
[email protected]
METABASE_PASSWORD=your-password
EOF

# 3. Pull all existing resources from Metabase
npx metabase-iac pull

# 4. You now have collections/, questions/, dashboards/ — commit them to git
git init && git add -A && git commit -m "Initial pull from Metabase"

Commands

| Command | Description | |---|---| | metabase-iac pull | Import collections, questions, and dashboards from Metabase | | metabase-iac plan | Preview what changes would be applied (dry run) | | metabase-iac apply | Push local resource definitions to Metabase | | metabase-iac databases | List connected databases | | metabase-iac collections | List collections |

Options

pull
  -o, --output <dir>         Output directory (default: ".")
  --import-base <path>       Import path for types in generated files (default: "metabase-iac/types")

plan / apply
  -d, --dir <dir>            Resources directory (default: ".")

Authentication

Configure via environment variables or a .env file:

METABASE_URL=https://your-metabase.example.com

# Option 1: Username + password
[email protected]
METABASE_PASSWORD=your-password

# Option 2: Session token
METABASE_SESSION_TOKEN=your-session-token

# Option 3: API key
METABASE_API_KEY=mb_xxxx

Resource types

Collections

import { collection } from 'metabase-iac/types'

export default collection({
  id: 23,
  slug: 'engineering',
  name: 'Engineering',
  description: 'Engineering team dashboards',
  parent: 'Teams', // optional — omit for root
})

Native queries (SQL)

Two files: a .sql with the query and a .meta.json with metadata.

-- questions/daily-signups.sql
SELECT date_trunc('day', created_at) AS day, count(*)
FROM users
GROUP BY 1
ORDER BY 1 DESC
LIMIT 30
{
  "id": 42,
  "name": "Daily Signups",
  "collection": "Engineering",
  "database": "production",
  "display": "line",
  "description": "Daily user signups over the last 30 days"
}

Native queries (MongoDB)

Same pattern, with .mongodb extension:

[
  { "$match": { "status": "active" } },
  { "$group": { "_id": "$region", "count": { "$sum": 1 } } },
  { "$sort": { "count": -1 } }
]

Structured queries (MBQL)

import { structuredQuestion } from 'metabase-iac/types'

export default structuredQuestion({
  id: 37,
  name: 'accounts-count',
  collection: 'Engineering',
  database: 'production',
  display: 'scalar',
  datasetQuery: {
    stages: [{ aggregation: [["count", {}]], "source-table": 77 }],
    database: 2,
  },
})

Dashboards

import { dashboard } from 'metabase-iac/types'

export default dashboard({
  id: 3,
  name: 'Engineering Overview',
  collection: 'Engineering',
  cards: [
    { question: 'Daily Signups', questionId: 42, width: 12, height: 6, row: 0, col: 0 },
    { question: 'accounts-count', questionId: 37, width: 6, height: 3, row: 0, col: 12 },
    { text: '## Notes\nUpdated daily.', width: 24, height: 2, row: 6, col: 0 },
  ],
})

Workflow

pull → review diff → edit → plan → apply → commit
  1. metabase-iac pull — import current state from Metabase
  2. Review changes with git diff
  3. Edit .ts/.sql/.mongodb files as needed
  4. metabase-iac plan — preview what will change
  5. metabase-iac apply — push to Metabase
  6. git commit — version control your changes

Project structure

A consumer repo looks like this:

my-metabase/
├── collections/
│   └── *.ts
├── questions/
│   ├── *.ts              # Structured (MBQL) queries
│   ├── *.sql             # Native SQL queries
│   ├── *.mongodb          # Native MongoDB queries
│   └── *.meta.json       # Metadata for native queries
├── dashboards/
│   └── *.ts
├── .env                  # Credentials (gitignored)
├── .gitignore
├── package.json
└── tsconfig.json         # Optional — for IDE type checking

How it works

  • Pull reads from the Metabase REST API and generates typed resource files
  • Plan/Apply loads local resource files, diffs against a state file (.metabase-state.json), and creates/updates resources via the API
  • Resources are matched by name within their collection
  • Ordering is automatic: collections are created before questions, questions before dashboards
  • Both SQL and MongoDB databases are fully supported — native queries are stored as plain text files

License

MIT