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

@clinikapi/react

v0.3.1

Published

Pre-built clinical UI widgets for React using the ClinikAPI proxy pattern. 14 responsive, themeable components built on shadcn/ui + Radix.

Readme

@clinikapi/react

Pre-built clinical UI widgets for React, built on shadcn/ui + Radix. Displays patient data, vitals, appointments, prescriptions, and more — all through a secure proxy pattern that never exposes your API key.

Install

npm install @clinikapi/react

Then import the stylesheet once, anywhere in your app:

import '@clinikapi/react/styles.css';

That's the whole setup. The stylesheet is self-contained and every rule in it is scoped to the widgets' own root element, so it cannot restyle your pages — and you don't need Tailwind, or any particular build setup, to use it.

Upgrading from 0.2.x? The widgets were rebuilt on shadcn/ui. Add the styles.css import above — without it they render unstyled. No component props changed.

How It Works

These widgets run in the browser and communicate with your backend proxy — never directly with ClinikAPI. Your backend calls the SDK with your secret key, and the widget displays the results.

Browser Widget → Your Backend Proxy → @clinikapi/sdk → ClinikAPI

Quick Start

1. Set up a backend proxy

// app/api/clinik/route.ts (Next.js)
import { Clinik } from '@clinikapi/sdk';

const clinik = new Clinik(process.env.CLINIKAPI_SECRET_KEY!);

export async function POST(req: Request) {
  const { action, data } = await req.json();

  // Authenticate the user with YOUR auth system first
  switch (action) {
    case 'patients.read':
      return Response.json(await clinik.patients.read(data.id, { include: data.include }));
    case 'patients.create':
      return Response.json(await clinik.patients.create(data));
    case 'appointments.create':
      return Response.json(await clinik.appointments.create(data));
    case 'prescriptions.create':
      return Response.json(await clinik.prescriptions.create(data));
    case 'notes.create':
      return Response.json(await clinik.notes.create(data));
    case 'intakes.submit':
      return Response.json(await clinik.intakes.submit(data));
    case 'consents.sign':
      return Response.json(await clinik.consents.sign(data));
    case 'observations.create':
      return Response.json(await clinik.observations.create(data));
    case 'labs.create':
      return Response.json(await clinik.labs.create(data));
    default:
      return Response.json({ error: 'Unknown action' }, { status: 400 });
  }
}

2. Use a widget

import { PatientDashboard } from '@clinikapi/react';

export default function PatientPage({ patientId }: { patientId: string }) {
  return (
    <PatientDashboard
      proxyUrl="/api/clinik"
      patientId={patientId}
    />
  );
}

Available Widgets

| Widget | Description | Key Fields | |--------|-------------|------------| | PatientDashboard | Full patient overview — demographics, encounters, vitals, meds, labs, notes | 3 themes (light, dark, glassmorphism) | | AppointmentScheduler | Book appointments | date, time, type, serviceType, specialty, priority, description | | PrescriptionForm | Write prescriptions | medication, dosage, priority, category, courseOfTherapy, substitution | | NoteEditor | Clinical note editor | title, content, type, docStatus, category, practiceSetting | | IntakeForm | Patient intake questionnaire | items with text, boolean, integer, coded, quantity answers | | ConsentManager | Consent signing | scope, category, verification, provision rules | | VitalsWidget | Record vital signs | heart rate, blood pressure | | LabResultsWidget | Order lab reports | LOINC codes, category, effectiveDateTime | | PrescriptionWidget | Quick medication entry | medication name, status | | ConditionTracker | Record conditions/diagnoses | code, clinicalStatus, severity, onset | | AllergyRecorder | Record allergies/intolerances | allergen, type, category, criticality, reaction | | ImmunizationLogger | Log immunizations | vaccine, site, route, lot number, manufacturer | | CarePlanBuilder | Create care plans | title, description, status, intent, category | | GoalSetter | Set patient goals | description, lifecycle, achievement, priority, target date |

Common Props

All widgets accept:

| Prop | Type | Required | Description | |------|------|----------|-------------| | proxyUrl | string | Yes | Your backend proxy endpoint (or 'demo' for demo mode) | | patientId | string | Yes | Patient ID | | theme | 'light' \| 'dark' \| 'glassmorphism' \| 'inherit' | No | Colour theme — see below | | className | string | No | Extra classes on the widget root |

Theming

Widgets read a set of --ck-* CSS custom properties. Override any of them to match your brand — the values are HSL channels, the same convention shadcn/ui uses:

.clinik-root {
  --ck-primary: 173 80% 40%;   /* teal */
  --ck-radius: 0.375rem;       /* squarer corners */
}

The full token set is --ck-background, --ck-foreground, --ck-card, --ck-popover, --ck-primary, --ck-secondary, --ck-muted, --ck-accent, --ck-destructive, --ck-success, --ck-border, --ck-input, --ck-ring, --ck-radius (each with a matching -foreground where it applies).

Already using shadcn/ui? Pass theme="inherit" and the widgets map straight onto your app's own --primary / --border / --radius variables, so they match your design system with no configuration:

<PatientDashboard proxyUrl="/api/clinik" theme="inherit" />

This is opt-in rather than automatic, because an app that isn't using shadcn/ui may well define --primary in a different format (a hex, say), which would render the widgets incorrectly.

Demo Mode

Set proxyUrl="demo" to run any widget without a backend — no API calls made.

<PatientDashboard proxyUrl="demo" />
<AppointmentScheduler proxyUrl="demo" patientId="demo-patient" />

Security

  • Widgets never receive your API key
  • All data flows through your backend proxy
  • You control authentication and authorization on your proxy endpoint
  • proxyUrl is validated to prevent open redirect attacks — must be relative path or same-origin

Requirements

  • React 18 or 19
  • A backend proxy that calls @clinikapi/sdk

Documentation

Full docs at docs.clinikapi.com/components

License

MIT