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

@mt-tl/studio

v0.1.9

Published

Self-hosted interactive explorer + playground for an MTProto TL schema — the "Swagger/Redoc for MTProto". Point it at your .tl layers, get a static doc site with a layer-aware reference, scenario guides and a try-it playground.

Readme

@mt-tl/studio

A self-hosted, interactive explorer + playground for an MTProto TL schema — the "Swagger/Redoc for MTProto". Point it at your .tl layers and get a static site with a layer-aware reference, a full schema view, a changelog, prose guides, and a live "try it" playground that speaks real MTProto from the browser.

It ships a pre-built static app; a small CLI assembles a site by generating the data files (api.json, wire.json, …) from your schema and copying them next to the app.

Two ways to use it

  • (a) Alongside @mt-tl/server — deploy the site next to your gateway and read your own docs / run live calls against your ws:// server (try-it + scenario runner + listener).
  • (b) Standalone docs (like Docusaurus) — point it at a directory of .tl files, publish the static site (e.g. GitHub Pages) for your team. No server required to browse.

Install

Requires Node 20+. Installs a mt-tl-studio CLI; the package ships the pre-built explorer UI, so there's nothing else to set up.

npm i -D @mt-tl/studio        # or: yarn add -D @mt-tl/studio

Building a server with @mt-tl/server? The framework docs have a walkthrough of Studio in context: the Studio guide.

Quick start

Put your per-layer schema as scheme_<N>.tl (one file per layer; each is the full schema at that layer) in a directory, then build:

mt-tl-studio build --layers ./schema --out ./site
npx serve ./site               # browse http://localhost:3000

--layers accepts either raw scheme_<N>.tl files or frozen scheme_<N>.json snapshots (the framework's mt-tl freeze output); .json wins when both exist. Using a custom filename prefix? Pass --prefix <p> (default scheme_) — it must match the prefix the layers were frozen with, e.g. --prefix layer_ for layer_<N>.json.

Authoring docs (incremental)

Everything below is optional — add it over time. Re-run build to regenerate.

mt-tl-studio build \
  --layers ./schema --out ./site \
  --descriptions ./descriptions \   # <symbol>.md  → rendered on method/type/constructor pages
  --scenarios ./scenarios \         # <folder>/<guide>.md → grouped guides (tree in the sidebar)
  --changelog ./changelog           # <layer>.md   → prose intro above the auto-diff
  • descriptions/account.checkFields.md, User.md, … Markdown shown on each page.
  • scenarios/ — guides in folders, e.g. auth/login.md. Embed a fenced ```scenario block (mt-tl-test YAML) to make a guide runnable — the studio shows a ▶ badge and an "open as interactive scenario" button that pre-fills the builder.
  • changelog/205.md etc.; the per-layer prose sits above the auto-generated added / changed / removed diff.

Try it (live calls)

In the connection bar: set your server ws:// URL and paste its RSA public key (PEM) (clients pin it for the handshake). Then call methods on the method page, build multi-user scenarios, or watch pushed updates on the Listen page. Auth is per-request: auth:false methods run anonymously; for logged-in flows write an auth recipe — a small ES module that default-exports async (ctx) => { … } and does your login (it may import your own crypto to sign at runtime).

By default the client speaks the mt-tl MTProto profile (RSA-pinned via the PEM you provide, plain intermediate framing) — for servers built with @mt-tl/server.

Talking to real Telegram. Tick obfuscated transport (Telegram) in the key panel and the client switches to the WebSocket transport Telegram requires (Sec-WebSocket-Protocol: binary + the obfuscated/AES-CTR stream). Paste Telegram's server RSA key, set your api_id (from my.telegram.org), point the URL at a Telegram WS endpoint (e.g. wss://venus.web.telegram.org/apiws_test for the test DC), and unauthenticated calls like help.getConfig work. Logged-in methods still need the full Telegram auth flow.

CLI

mt-tl-studio build --layers <dir> --out <dir>
    [--prefix <p>] [--protocol <dir>] [--descriptions <dir>] [--scenarios <dir>] [--changelog <dir>] [--recipes <dir>]
    [--default-url <ws-url>] [--default-key <pem-file>] [--default-obfuscated]

The reference renders your business API only — low-level MTProto types (handshake, service messages, vector, rpc_error, …) are hidden; the initConnection/invokeWithLayer wrappers stay. The playground still loads the full protocol, so live calls work.

  • --prefix <p> — snapshot filename prefix (default scheme_). Must match the prefix the layers were frozen with (mt-tl freeze … --prefix).

  • --protocol <dir> — your overridden protocol schema (dir or .tl), the same one the server runs with. Hides its low-level types from the docs and lets the playground speak it.

  • --recipes <dir> — bundle ready auth recipes (<name>.js/.mjs ES modules, optional <name>.args.json) so your team reuses them out of the box (shown alongside locally-saved ones).

  • --default-url / --default-key — bake a default ws:// URL + server RSA public-key PEM into the site (config.json); the connection bar seeds from them (a user's own saved value still wins). Handy for a team deployment so nobody pastes the URL/key by hand.

  • --default-obfuscated — default the obfuscated WebSocket transport on. Required to talk to real Telegram (which also needs its server RSA key + your api_id); leave it off for an @mt-tl/server gateway.

Host <out> on any static host (GitHub Pages, S3, nginx, …).