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

@morscherlab/mint-sdk

v1.0.45

Published

MINT Platform SDK — Vue 3 components, composables, and types for plugin development. MINT = Mass-spec INtegrated Toolkit.

Downloads

6,737

Readme

@morscherlab/mint-sdk (Frontend)

Vue 3 SDK for MINT Platform plugin development. Provides reusable components, composables, stores, and types for building consistent, well-integrated plugins.

Full Documentation: See the comprehensive docs for detailed API reference and guides.

Installation

bun add @morscherlab/mint-sdk

Requirements

  • Vue 3.4+
  • Pinia 2.1+
  • Tailwind CSS 4.0+ (optional - SDK includes pre-built utility classes)

Quick Start

1. Import Styles

Import the SDK styles in your main entry point:

// main.ts
import '@morscherlab/mint-sdk/styles'

The SDK includes all necessary CSS utility classes pre-built, so Tailwind CSS is optional. The styles work standalone or alongside Tailwind.

2. (Optional) Configure Tailwind

If you're using Tailwind CSS and want to extend the MINT theme:

import mintPreset from '@morscherlab/mint-sdk/tailwind.preset'

export default {
  presets: [mintPreset],
  content: [
    './src/**/*.vue',
    './node_modules/@morscherlab/mint-sdk/**/*.vue',
  ],
}

3. Use Components

<script setup lang="ts">
import { BaseButton, BaseInput, FormField } from '@morscherlab/mint-sdk'
import { useToast, useAuth } from '@morscherlab/mint-sdk'
import type { ButtonVariant } from '@morscherlab/mint-sdk'

const { success } = useToast()
const { login } = useAuth()

async function handleSubmit() {
  const result = await login(username, password)
  if (result) {
    success('Login successful!')
  }
}
</script>

<template>
  <FormField label="Username" required>
    <BaseInput v-model="username" placeholder="Enter username" />
  </FormField>

  <BaseButton variant="primary" @click="handleSubmit">
    Login
  </BaseButton>
</template>

4. Use Generated Plugin Clients

For plugin frontends scaffolded by mint init, run this from the plugin root:

mint sdk generate

Use mint sdk generate --check --json when CI or editor tasks need machine-readable contract drift status.

Then call backend routes through the generated client:

import { useGeneratedPluginClient } from './generated/mint-plugin'

const pluginClient = useGeneratedPluginClient()
const health = await pluginClient.health()

Generated files also expose typed plugin settings when the backend declares a settings_model:

import { useGeneratedPluginSettings } from './generated/mint-plugin'

const { settings } = useGeneratedPluginSettings()
const threshold = settings.value?.threshold

The generated client is built from backend plugin metadata, FastAPI routes, and Pydantic schemas, and uses the frontend SDK to resolve the API prefix automatically. Routes with an experimentId path parameter can omit it inside an experiment page; the client reads the current platform experiment from injected context or the URL:

await pluginClient.analyze({ body: { parameters: { threshold: '0.05' } } })

Use useCurrentExperiment() when a plugin view needs the platform experiment selected in the URL or injected context:

import { useCurrentExperiment } from '@morscherlab/mint-sdk'

const {
  experimentId,
  hasExperiment,
  requireExperimentId,
  experiment,
  isLoading,
  refresh,
} = useCurrentExperiment()

async function saveCurrentExperiment() {
  if (!hasExperiment.value) return
  const id = requireExperimentId()
  // Use id for platform APIs or explicit cross-experiment overrides.
}

5. Use Biology Data Templates

Plugin frontends can import standard biology template builders and adapters instead of inventing ad-hoc JSON shapes:

import {
  createWellPlateScreenCollection,
  createTemplateCollection,
  createPlateMapTemplate,
  createSampleSheetTemplate,
  ensureTemplateFromCollection,
  listBioTemplateCatalog,
  listBioTemplatePresets,
  toPlateMapEditorState,
  toTemplateDataFrame,
} from '@morscherlab/mint-sdk/templates'

const catalog = listBioTemplateCatalog()
const presets = listBioTemplatePresets()
const template = createPlateMapTemplate({
  samples: ['Control', 'Treatment'],
})
const plateEditorState = toPlateMapEditorState(template)

const sampleFrame = toTemplateDataFrame(createSampleSheetTemplate({
  samples: [{ sampleId: 'S001', name: 'Control 1' }],
}))
// <DataFrame v-bind="sampleFrame" />

const collection = createTemplateCollection([template])
const loadedPlate = ensureTemplateFromCollection(collection, 'plate-map')

const screenCollection = createWellPlateScreenCollection({
  samples: ['Control', 'Treatment'],
  compounds: { 'Drug A': [10, 1, 0.1] },
  unit: 'uM',
})

For frontend wiring, useBioTemplateWorkspace() combines the generated controls, sidebar/forms, renderer props, and SDK component bindings:

import { useBioTemplateWorkspace } from '@morscherlab/mint-sdk'
import { createWellPlateScreenCollection } from '@morscherlab/mint-sdk/templates'

const collection = createWellPlateScreenCollection({
  samples: ['Control', 'Treatment'],
  compounds: { 'Drug A': [10, 1, 0.1] },
})
const workspace = useBioTemplateWorkspace(collection)

// <AppSidebar v-bind="workspace.sidebar" />
// <FormBuilder v-bind="workspace.form" />
// <BioTemplateRenderer v-if="workspace.renderer" v-bind="workspace.renderer" />

For editable built-in presets, useBioTemplatePresetWorkspace() also manages the generated control values, collection updates, and current-experiment save:

import { BioTemplatePresetWorkspaceView, useBioTemplatePresetWorkspace } from '@morscherlab/mint-sdk'

const workspace = useBioTemplatePresetWorkspace('wellplate-screen')

// <BioTemplatePresetWorkspaceView :workspace="workspace" />

For custom plugin tools, pass one workspace model to ControlWorkspaceView to generate AppTopBar, AppSidebar, FormBuilder, component prop bindings, and their shared values from the same source:

<script setup lang="ts">
import { ref } from 'vue'
import { ControlWorkspaceView, defineControlModel } from '@morscherlab/mint-sdk'

const workspaceModel = defineControlModel({
  views: {
    analysis: {
      label: 'Analysis',
      sections: {
        parameters: {
          label: 'Parameters',
          controls: {
            threshold: { type: 'number', default: 0.05, min: 0, max: 1 },
            method: ['linear', 'logistic'],
            saveResults: true,
          },
        },
      },
    },
  },
})
const values = ref({})
</script>

<template>
  <ControlWorkspaceView v-model="values" :model="workspaceModel" title="Analysis" />
</template>

Use defineControls() for flat forms, and use useControlWorkspace() directly only when a plugin needs full manual control over the generated AppTopBar, AppSidebar, or FormBuilder bindings.

For WellPlate + DoseCalculator pages, start from the dose-design preset instead of writing the sidebar controls and component prop mappings yourself:

<script setup lang="ts">
import { ControlWorkspaceView, DoseCalculator, WellPlate, defineDoseDesignControlModel } from '@morscherlab/mint-sdk'

const workspaceModel = defineDoseDesignControlModel({
  selectedWells: ['A1', 'A2'],
  includeMolecularWeight: true,
})
</script>

<template>
  <ControlWorkspaceView :model="workspaceModel" title="Dose Design" v-slot="{ componentPropsById }">
    <WellPlate v-bind="componentPropsById.plate" />
    <DoseCalculator v-bind="componentPropsById.dose" />
  </ControlWorkspaceView>
</template>

Built-in templates include plate-map, sample-sheet, sample-prep, dose-response, calibration-curve, time-course, protocol-steps, assay-matrix, reagent-list, flow-cytometry-panel, instrument-run, and qpcr-plate. In plugin projects, mint add data-template <name> --page generates the matching backend route, typed frontend composable, and starter view. Generated composables use ensureTemplateEnvelope() to validate backend template payloads before assigning typed frontend state. Use createTemplateCollection(), extractTemplateCollection(), and ensureTemplateFromCollection() when a plugin view reads or writes the shared design_data.templates layout. mint add data-template-pack <name> --page generates a pack-level composable that uses these helpers for curated experiment scaffolds. Use mint add data-template-pack <name> --page for curated sets such as cell-culture-screen, omics-assay, longitudinal-study, and molecular-assay. For no-scaffold defaults that can be saved directly to design_data, use template presets such as createWellPlateScreenCollection(), createQpcrExpressionCollection(), createLcmsBatchCollection(), and createWesternBlotAssayCollection().

Components

Base Components

  • BaseButton - Button with variants (primary, secondary, cta, danger, success, ghost)
  • BaseInput - Text input with validation states
  • BaseSelect - Dropdown select with generic typing
  • BaseTabs - Tab navigation with underline and pills variants
  • BaseModal - Modal dialog with Teleport

Form Components

  • FormField - Form field wrapper with label, error, and hint
  • FormBuilder - Schema-driven forms from full schema objects or compact controls

Feedback Components

  • AlertBox - Alert messages (success, error, warning, info)
  • AppToastContainer - Toast notification container for the global useToast() queue

Action Components

  • IconButton - Icon-only button with accessibility
  • ThemeToggle - Light/dark mode toggle

Layout Components

  • CollapsibleCard - Expandable card sections with optional icon badge and toggle switch
  • AppTopBar - Application header with slots
  • AppSidebar - Context sidebar that accepts panels/forms or a compact controls schema

Biological Template Components

  • BioTemplateRenderer - Render template envelopes or collections with matching SDK components
  • BioTemplateExperimentWorkspaceView - Current-experiment load/save/reset workspace for one template or collection
  • BioTemplatePresetWorkspaceView - Full editable preset workspace from useBioTemplatePresetWorkspace()

File & Data Components

  • FileUploader - Drag-and-drop file upload with file/folder mode support

Sample Management Components

  • SampleSelector - Hierarchical sample grouping with auto-group, CSV metadata import, and optional experiment design_data sample loading
  • AutoGroupModal - Smart sample grouping wizard for names and design metadata
  • GroupAssigner - Drag-and-drop group assignment for comparisons (e.g., Control vs Treatment)

Removed Compatibility APIs

The public SDK no longer exports ToastNotification, GroupingModal, SettingsButton, FormSection, FormFieldRenderer, or usePluginApi(). Use AppToastContainer, AutoGroupModal, AppTopBar settings or SettingsModal, FormBuilder, and generated useGeneratedPluginClient() helpers instead. mint doctor still detects old imports and reports the replacement path.

Composables

useApi(options?)

Generic API client with auth interceptor.

const api = useApi()

// GET request
const data = await api.get<User[]>('/users')

// POST with body
const created = await api.post<User>('/users', { name: 'John' })

// File upload
const result = await api.upload<UploadResponse>('/upload', file)

// Build URLs for external use
const downloadUrl = api.buildUrl('/files/123/download')

useAuth()

Authentication methods.

const { login, logout, initializeAuth, getCurrentUser } = useAuth()

// Initialize on app mount
await initializeAuth()

// Login
const success = await login(username, password)

// Get current user
const user = await getCurrentUser()

usePasskey()

WebAuthn/FIDO2 passkey support.

const { isSupported, registerPasskey, loginWithPasskey } = usePasskey()

if (isSupported()) {
  await registerPasskey('My Device')
  // or
  await loginWithPasskey()
}

useTheme()

Theme switching.

const { isDark, toggleTheme, setTheme } = useTheme()

toggleTheme()
setTheme(true) // dark mode

useToast()

Toast notification management.

const { success, error, warning, info } = useToast()

success('Operation completed!')
error('Something went wrong')
warning('Please review your input')
info('New update available')

usePlatformContext()

Detect and interact with MINT Platform when running as a plugin.

const { isIntegrated, plugin, user, navigate, notify } = usePlatformContext()

if (isIntegrated.value) {
  // Running under MINT Platform
  console.log('Plugin:', plugin.value?.name)
  notify('Hello from plugin!', 'info')
}

useExperimentSamples(options?)

Load experiment design_data and derive SampleSelector-compatible sample values.

const { samples, sampleOptions, fetch } = useExperimentSamples({ experimentId: 42 })
await fetch()

Stores

useAuthStore

Pinia store for authentication state.

const authStore = useAuthStore()

// State
authStore.token
authStore.userInfo
authStore.isAuthenticated
authStore.isAdmin

// Actions
authStore.initialize()
authStore.setToken(token, expiresIn)
authStore.logout()

useSettingsStore

Pinia store for app settings.

const settingsStore = useSettingsStore()

// State
settingsStore.theme // 'light' | 'dark' | 'system'
settingsStore.colorPalette

// Methods
settingsStore.getApiBaseUrl()
settingsStore.getWsBaseUrl()
settingsStore.isDark()

TypeScript Types

All types are exported from @morscherlab/mint-sdk:

import type {
  // Components
  ButtonVariant,
  ButtonSize,
  ModalSize,
  AlertType,
  Toast,
  TabItem,
  SelectOption,

  // Sample Management
  SampleGroup,      // { name, color, samples[] }
  GroupItem,        // { name, color, count }
  FileUploaderMode, // 'file' | 'folder'

  // Auth
  AuthConfig,
  UserInfo,
  LoginResponse,

  // Platform
  PluginInfo,
  PlatformContext,
  ThemeMode,
} from '@morscherlab/mint-sdk'

CSS Utility Classes

The SDK provides ready-to-use CSS classes:

Buttons

  • .btn-primary - Blue primary button
  • .btn-secondary - Outlined/bordered button
  • .btn-cta - Orange call-to-action button
  • .btn-success - Green success button
  • .btn-danger - Red danger button

Inputs

  • .input-modern - Styled text input
  • .select-modern - Styled dropdown select
  • .label-modern - Uppercase label

Cards & Containers

  • .card - Card with border and shadow
  • .card-hover - Card with hover effect
  • .floating-card - Floating container pattern

Alerts

  • .alert-success - Green success alert
  • .alert-error - Red error alert
  • .alert-warning - Yellow warning alert
  • .alert-info - Blue info alert

Form Controls

  • .toggle-switch - Toggle switch
  • .checkbox-modern - Styled checkbox

Theming

The SDK uses CSS variables for theming. Override them to customize:

:root {
  --bg-primary: #F8FAFC;
  --bg-secondary: #FFFFFF;
  --bg-tertiary: #F1F5F9;
  --text-primary: #1E293B;
  --text-secondary: #64748B;
  --border-color: #E5E7EB;
  --color-primary: #3B82F6;
}

html.dark {
  --bg-primary: #0F172A;
  --bg-secondary: #1E293B;
  --bg-tertiary: #334155;
  --text-primary: #F8FAFC;
  --text-secondary: #94A3B8;
  --border-color: #334155;
}

License

MIT