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

@maestrio/sdk

v0.0.2

Published

Official JavaScript/TypeScript SDK for [Maestrio](https://app.maestrio.com) — submit bug reports and feature requests from your app.

Readme

@maestrio/sdk

Official JavaScript/TypeScript SDK for Maestrio — submit bug reports and feature requests from your app.

Installation

npm install @maestrio/sdk
# or
pnpm add @maestrio/sdk
# or
yarn add @maestrio/sdk

CDN (UMD)

<script src="https://unpkg.com/@maestrio/sdk"></script>
<script>
  const maestrio = Maestrio.createMaestrio({
    apiKey: "mst_...",
    baseUrl: "https://app.maestrio.com",
    projectId: "your-project-id",
  });
</script>

Quick Start

import { createMaestrio } from "@maestrio/sdk";

const maestrio = createMaestrio({
  apiKey: "mst_...",
  baseUrl: "https://app.maestrio.com",
  projectId: "your-project-id",
});

// Identify the current user
maestrio.identify("user-123", {
  name: "Jane Doe",
  email: "[email protected]",
});

// Submit a bug report
const result = await maestrio.submitRequest({
  title: "Button doesn't work",
  description: "The submit button on the settings page is unresponsive.",
  type: "bug",
});

result.match({
  ok: (data) => console.log("Request created:", data.id),
  err: (error) => console.error("Failed:", error.message),
});

API Reference

createMaestrio(config)

Creates a new Maestrio SDK instance.

const maestrio = createMaestrio({
  apiKey: string;      // Your Maestrio API key
  baseUrl: string;     // Maestrio API base URL
  projectId: string;   // Your project identifier
  widget?: WidgetConfig; // Optional widget customization
});

maestrio.identify(userId, userProperties?, systemProperties?)

Identifies the current user. Must be called before submitRequest() or show().

maestrio.identify(
  "user-123",
  { name: "Jane", email: "[email protected]", avatar: "https://..." },
  { autoShow: true }, // automatically call show() after identifying
);

| Parameter | Type | Description | | ------------------ | ------------------ | -------------------------------- | | userId | string | Unique user identifier | | userProperties | UserProperties? | Optional user metadata | | systemProperties | SystemProperties?| Options like autoShow (default false) |

maestrio.submitRequest(params)

Submits a bug report or feature request. Returns a Result (from better-result).

const result = await maestrio.submitRequest({
  title: "Add dark mode",
  description: "Please add a dark mode toggle to settings.",
  type: "feature", // "bug" | "feature"
});

Success response:

{ id: string; status: string; queued: boolean }

maestrio.show()

Opens the feedback widget. Requires a prior identify() call.

maestrio.hide()

Closes the feedback widget.

maestrio.destroy()

Removes the widget from the DOM and cleans up all resources.

Widget Customization

Position

Control where the widget appears on screen:

createMaestrio({
  apiKey: "mst_...",
  baseUrl: "https://app.maestrio.com",
  projectId: "your-project-id",
  widget: {
    position: "right-center-vertical", // "right-center-horizontal" | "right-center-vertical"
  },
});

Theme

Override the widget's visual style by passing a theme object. Under the hood, each theme property maps to a CSS custom property on the <maestrio-widget> web component. When you pass a theme value, the SDK calls style.setProperty() on the host element, overriding the built-in defaults.

How it works

The widget renders inside a Shadow DOM, so its styles are fully isolated from your app. All visual tokens are defined as CSS custom properties on the :host element:

:host {
  --maestrio-primary: #4a7c59;
  --maestrio-primary-foreground: #ffffff;
  --maestrio-bg: #ffffff;
  --maestrio-text: #1a1a1a;
  --maestrio-text-secondary: #6b7280;
  --maestrio-border: #e5e7eb;
  --maestrio-input-bg: #f5f5f5;
  --maestrio-radius: 12px;
  --maestrio-font: system-ui, -apple-system, sans-serif;
}

When you provide a theme in the config, each key is mapped to its corresponding CSS variable and applied at runtime:

| Theme Property | CSS Variable | Default | Used for | | --- | --- | --- | --- | | primaryColor | --maestrio-primary | #4a7c59 | Buttons, accents, focus rings, selected states | | primaryForeground | --maestrio-primary-foreground | #ffffff | Text/icon color on primary elements | | backgroundColor | --maestrio-bg | #ffffff | Modal panel background | | textColor | --maestrio-text | #1a1a1a | Headings, labels, body text | | borderRadius | --maestrio-radius | 12px | Modal corners, buttons, inputs (derived via calc) |

Usage

createMaestrio({
  // ...
  widget: {
    theme: {
      primaryColor: "#6366f1",
      primaryForeground: "#ffffff",
      backgroundColor: "#1e1e2e",
      textColor: "#cdd6f4",
      borderRadius: "12px",
    },
  },
});

All theme properties are optional — only the values you provide will override the defaults.

Derived values

Some internal CSS variables are not directly configurable through the theme object but are derived from the tokens above:

  • --maestrio-text-secondary (#6b7280) — used for descriptions and placeholders
  • --maestrio-border (#e5e7eb) — used for card borders, input borders, dividers
  • --maestrio-input-bg (#f5f5f5) — used for textarea and card backgrounds
  • --maestrio-font (system-ui, -apple-system, sans-serif) — widget font stack

Border radius is automatically scaled down for inner elements (buttons, inputs, cards) using calc(var(--maestrio-radius) - 2px) and calc(var(--maestrio-radius) - 4px), so changing borderRadius keeps proportions consistent across the entire widget.

Labels

Override any user-facing text in the widget. All label properties are optional — defaults are used for any you don't provide.

createMaestrio({
  // ...
  widget: {
    labels: {
      triggerText: "Feedback",
      headerText: "Send us feedback",
      bugLabel: "Report a Bug",
      bugDescription: "Something isn't working as expected",
      suggestionLabel: "Suggestion",
      suggestionDescription: "Got an idea? We'd love to hear it.",
      bugPlaceholder: "Describe the problem and when it happened...",
      suggestionPlaceholder: "Describe what you'd like to see...",
      bugTextareaLabel: "What went wrong?",
      suggestionTextareaLabel: "What would you like to see?",
      sendButton: "Send",
      cancelButton: "Cancel",
    },
  },
});

| Label | Default | Description | | --- | --- | --- | | triggerText | "Feedback" | Floating trigger button text | | headerText | "What is your feedback?" | Modal title | | bugLabel | "Bug" | Bug card heading | | bugDescription | "Found a problem? Let us know." | Bug card subtext | | suggestionLabel | "Suggestion" | Feature card heading | | suggestionDescription | "Got an idea? We'd love to hear it." | Feature card subtext | | bugPlaceholder | "Describe the problem and when it happened..." | Textarea placeholder for bugs | | suggestionPlaceholder | "Describe what you'd like to see..." | Textarea placeholder for features | | bugTextareaLabel | "What went wrong?" | Textarea label for bugs | | suggestionTextareaLabel | "What would you like to see?" | Textarea label for features | | sendButton | "Send" | Submit button text | | cancelButton | "Cancel" | Cancel button text |

Full Example

const maestrio = createMaestrio({
  apiKey: "mst_...",
  baseUrl: "https://app.maestrio.com",
  projectId: "your-project-id",
  widget: {
    position: "right-center-vertical",
    theme: {
      primaryColor: "#6366f1",
      primaryForeground: "#ffffff",
      backgroundColor: "#ffffff",
      textColor: "#1f2937",
      borderRadius: "8px",
    },
    labels: {
      triggerText: "Help & Feedback",
      headerText: "How can we help?",
    },
  },
});

Error Handling

The SDK uses the Result pattern instead of throwing errors.

import { NotIdentifiedError, ApiError, NetworkError, ValidationError } from "@maestrio/sdk";

const result = await maestrio.submitRequest({ ... });

result.match({
  ok: (data) => {
    console.log("Created:", data.id);
  },
  err: (error) => {
    // error._tag tells you the type
    switch (error._tag) {
      case "NotIdentifiedError":
        console.error("Call identify() first");
        break;
      case "ApiError":
        console.error(`API error ${error.status}: ${error.message}`);
        break;
      case "NetworkError":
        console.error("Network failed:", error.message);
        break;
      case "ValidationError":
        console.error(`Invalid ${error.field}: ${error.message}`);
        break;
    }
  },
});

TypeScript Types

All types are exported for use in your application:

import type {
  MaestrioConfig,
  MaestrioSDK,
  UserProperties,
  SystemProperties,
  RequestType,
  SubmitRequestParams,
  SubmitRequestResponse,
  SdkError,
} from "@maestrio/sdk";