Agent skill

Opentrons Typescript

by Opentrons in Opentrons/opentrons

TypeScript conventions, React patterns, testing, styling, and import rules for the Opentrons monorepo JS/TS packages.

Apache-2.0Auto-check passedDevelopment

Install Opentrons Typescript

skills CLI
$ npx skills add Opentrons/opentrons --skill opentrons-typescript -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Opentrons/opentrons opentrons-typescript --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Opentrons/opentrons.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.cursor/skills/opentrons-typescript .claude/skills/opentrons-typescript && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
opentrons-typescript
GitHub stars
523
Token cost
~3.7k tokens
SKILL.md length
955 words
Files
1
Skills in repo
17
Repo updated
First seen
Licence
Apache-2.0

At a glance

TypeScript conventions, React patterns, testing, styling, and import rules for the Opentrons monorepo JS/TS packages.

  • Works in 7 steps: React imports (import { useState } from… → Third-party packages → @opentrons/* packages → …
  • Working with TypeScript
  • SKILL.md covers Monorepo Structure, TypeScript Configuration, Code Style (Prettier) and Import Conventions, plus 4 more sections
  • Calls make, pnpm and tsc

What it does

Opentrons Typescript is an agent skill from Opentrons/opentrons. TypeScript conventions, React patterns, testing, styling, and import rules for the Opentrons monorepo JS/TS packages. Use when working with TypeScript or React files in app/, components/, shared-data/, step-generation/, protocol-designer/, protocol-visualization/, opentrons-ai-client/, or other JS/TS packages.

Its SKILL.md is about 3.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Monorepo tooling and React components. It works with TypeScript and React. The repository describes itself as: Software for writing protocols and running them on the Opentrons Flex and Opentrons OT-2. The licence is Apache-2.0.

When your agent uses it

  • Working with TypeScript
  • React files in app/
  • Step-generation/
  • Protocol-designer/

Example prompts

  • “/opentrons-typescript”

Requirements

  • Python 3
  • Node.js

Workflow steps

7 steps, taken from the first numbered list in SKILL.md.

  1. React imports (import { useState } from 'react')
  2. Third-party packages
  3. @opentrons/* packages
  4. Package-local absolute imports (/app/*, /protocol-designer/*, /ai-client/*)
  5. Relative imports
  6. import type (type-only imports, same sub-ordering)
  7. Asset imports (images, CSS)

What it can do on your machine

Read from SKILL.md and the folder at commit adb4970. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • make
    • pnpm
    • tsc

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Opentrons Typescript loads about 3.7k tokens when it runs. Until then it costs about 83 tokens; SKILL.md has 955 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~83
When it runs · the whole SKILL.md, loaded when a task matches
~3.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Opentrons/opentrons at commit adb4970, republished under its Apache-2.0 licence (© Opentrons). 955 words, ~3,687 tokens.

Download SKILL.mdSave it as .claude/skills/opentrons-typescript/SKILL.md (or your agent's skills folder).
name
opentrons-typescript
description
TypeScript conventions, React patterns, testing, styling, and import rules for the Opentrons monorepo JS/TS packages. Use when working with TypeScript or React files in app/, components/, shared-data/, step-generation/, protocol-designer/, protocol-visualization/, opentrons-ai-client/, or other JS/TS packages.

Opentrons Monorepo — TypeScript Conventions

Node.js, Pnpm, Python setup, teardown, and troubleshooting are in the always-apply monorepo-setup rule.

Monorepo Structure

Pnpm workspaces monorepo with 15 TypeScript packages. No Lerna/Nx/Turbo — uses Pnpm workspaces + TypeScript project references.

Packages
PackageDirectoryType
@opentrons/appapp/React app
@opentrons/app-shellapp-shell/Electron shell
@opentrons/app-shell-oddapp-shell-odd/Electron shell (ODD)
@opentrons/componentscomponents/React UI components library
@opentrons/api-clientapi-client/Pure TS library
@opentrons/react-api-clientreact-api-client/React hooks library
@opentrons/discovery-clientdiscovery-client/Pure TS (Node)
@opentrons/shared-datashared-data/Pure TS/JS data library
@opentrons/step-generationstep-generation/Pure TS library
@opentrons/labware-librarylabware-library/React app
@opentrons/labware-designerlabware-designer/React app
opentrons-ai-clientopentrons-ai-client/React app
protocol-designerprotocol-designer/React app
@opentrons/protocol-visualizationprotocol-visualization/React library (protocol viz, WIP)
@opentrons/usb-bridge-clientusb-bridge/node-client/Pure TS (Node)
Dependency Graph

shared-data is the foundation. Nothing should import "up" the tree:

markdown
shared-data
├── step-generation
├── components
├── api-client → react-api-client
└── discovery-client
↓
protocol-visualization (scaffold; depends on components + shared-data + step-generation)
↓
app, protocol-designer, labware-library, opentrons-ai-client (leaf apps)

TypeScript Configuration

All packages extend tsconfig-base.json:

  • Target/Module: ESNext
  • Strict: true (no any, strict null checks)
  • JSX: preserve (Vite handles transform)
  • Declarations: emitDeclarationOnly, composite for project references
  • Module resolution: node

Each package defines rootDir: "src", outDir: "lib", and references its dependencies.

Code Style (Prettier)

Enforced by Prettier with @ianvs/prettier-plugin-sort-imports:

  • No semicolons
  • Single quotes (double quotes in JSX)
  • Trailing commas: ES5
  • Print width: 80, Tab width: 2
  • Line endings: LF

Import Conventions

Order (auto-sorted by Prettier plugin)
  1. React imports (import { useState } from 'react')
  2. Third-party packages
  3. @opentrons/* packages
  4. Package-local absolute imports (/app/*, /protocol-designer/*, /ai-client/*)
  5. Relative imports
  6. import type (type-only imports, same sub-ordering)
  7. Asset imports (images, CSS)
Cross-Package Imports

Use the @opentrons/ scope. These resolve to source via Vite aliases in dev/test:

typescript
import { Flex, SPACING } from '@opentrons/components'
import { getPipetteSpecsV2 } from '@opentrons/shared-data'

import type { PipetteName } from '@opentrons/shared-data'
Intra-Package Absolute Imports

Each app has a path alias (configured in tsconfig + Vite):

  • app/ → /app/*
  • protocol-designer/ → /protocol-designer/*
  • opentrons-ai-client/ → /ai-client/*
typescript
// Good — absolute import within app
import { useRobot } from '/app/resources/robots'

// Bad — deep relative paths across features
import { useRobot } from '../../../resources/robots'
// Acceptable — relative for nearby files in the same feature
import { utils } from './utils'
No Default Exports

ESLint enforces import/no-default-export. Always use named exports. Exceptions: config files (vite.config.mts, *.stories.tsx).

Lodash

Import individual functions only:

typescript
// Good — imports a specific function
import mapValues from 'lodash/mapValues'
typescript
// Bad — imports entire library
import { mapValues } from 'lodash'
Type Imports

Always use import type for type-only imports:

typescript
import type { LabwareDefinition2 } from '@opentrons/shared-data'

React Component Patterns

Function Declarations (not arrows)
typescript
interface MyComponentProps {
  title: string
  onClose: () => void
}

export function MyComponent({ title, onClose }: MyComponentProps): JSX.Element {
  return <div>{title}</div>
}
  • Named function declarations, not arrow functions, for components
  • Props interface named <ComponentName>Props
  • Always destructure props in the function signature
Atomic Design Hierarchy

Components are organized as atoms/ → molecules/ → organisms/ → pages/. Custom ESLint rule opentrons/no-imports-up-the-tree-of-life prevents importing up the hierarchy:

  • atoms must NOT import from molecules, organisms, or pages
  • molecules must NOT import from organisms or pages
  • organisms must NOT import from pages
Application Boundaries (app/ specific)

The app package separates Desktop and ODD (On-Device Display) UIs. ESLint rule opentrons/no-imports-across-applications prevents cross-contamination between /Desktop/, /ODD/, and shared code.

Component Library (@opentrons/components)

Do not use primitives from the shared component library when you create a new component from zero. Primitives are located in components/src/primitives. Use primitives if you update an existing component or fix an existing component for layout and common UI:

typescript
import {
  COLORS,
  DIRECTION_COLUMN,
  Flex,
  Icon,
  SPACING,
  StyledText,
} from '@opentrons/components'
Hooks
  • useSelector / useDispatch from react-redux
  • useTranslation from react-i18next for i18n
  • Custom hooks prefixed with use*
  • Never call hooks conditionally
  • ESLint enforces react-hooks/rules-of-hooks (error) and react-hooks/exhaustive-deps (warn)

Styling

CSS Modules (preferred for new code)
  • File: <componentname>.module.css (lowercase, no separators)
  • Classes: snake_case (enforced by Stylelint: /^[a-z0-9_]+$/)
  • Use CSS custom properties from the design system (spacing, colors, typography, border-radius)
  • Use clsx for conditional classes
  • Never use inline styles in components (only in *.stories.tsx)
styled-components (legacy)

Some packages still use styled-components@5.3.6. Do not introduce new styled-components — use CSS Modules for new code.

Design System Tokens
css
/* Spacing */
padding: var(--spacing-8);
gap: var(--spacing-16);

/* Colors */
color: var(--grey-60);
background: var(--white);

/* Typography */
font-size: var(--font-size-13);
font-weight: var(--font-weight-semi-bold);

/* Border radius */
border-radius: var(--border-radius-8);

/* Width/height — use explicit rem values, NOT variables */
width: 15rem;

Testing

Framework
  • Vitest 2.1.9 (not Jest) — vi.fn(), vi.mock(), vi.mocked()
  • @testing-library/react 16.3.0 — screen, fireEvent, renderHook
  • @testing-library/user-event 14.6.1
  • vitest-when 0.5.0 for conditional mocking
  • jsdom test environment (global vitest.config.mts)
Test File Structure
markdown
FeatureOrComponent/
├── index.tsx (or module.ts)
└── **tests**/
└── FeatureName.test.tsx
renderWithProviders

React component tests MUST use renderWithProviders (wraps Redux Provider + QueryClientProvider + optional i18n), not plain render:

typescript
import { renderWithProviders } from '/app/__testing-utils__'  // or /protocol-designer/__testing-utils__
import { i18n } from '/app/i18n'
import type { ComponentProps } from 'react'

const render = (props: ComponentProps<typeof MyComponent>) => {
  return renderWithProviders(<MyComponent {...props} />)[0]
}

describe('MyComponent', () => {
  let props: ComponentProps<typeof MyComponent>

  beforeEach(() => {
    props = { /* defaults */ }
  })

  afterEach(() => {
    vi.clearAllMocks()
  })

  it('renders the button', () => {
    render(props)
    expect(screen.getByRole('button')).toBeInTheDocument()
  })

  it('renders the text', () => {
    render(props)
    screen.getByText('Opentrons Flex')
  })
})
Show full SKILL.md (386 more words)Show less
Mocking
  • vi.mock() at file top for module mocks
  • vi.mocked(fn).mockReturnValue(...) for typed mocks
  • vi.clearAllMocks() in afterEach (always)
Queries
  • Prefer screen.getByRole, screen.getByText, screen.getByTestId
  • Never use container.querySelector
  • data-testid format: ComponentName_ElementType

Makefile Targets

Per-Package (run from the package directory)

Each package has a Makefile with some or all of:

TargetDescription
make devStart Vite dev server
make buildProduction build
make cleanRemove build output
make testRun tests (delegates to root)
make test-covRun tests with coverage
Root Makefile (run from monorepo root)
TargetDescription
make setup-jsInstall all JS deps (pnpm)
make test-jsRun ALL JS tests
make test-js-<project>Run tests for one project (e.g., make test-js-protocol-designer)
make lint-jsESLint + Prettier check
make lint-js-eslintESLint only
make lint-js-prettierPrettier only
make lint-cssStylelint all CSS
make format-jsAuto-format with Prettier
make format-cssAuto-fix CSS with Stylelint
make check-js / make build-tsTypeScript type-check (tsc --build)
make clean-tsClean TS build output
make circular-dependencies-jsCheck circular imports (madge)
Running Tests Directly
bash
# Single file
pnpm vitest app/src/organisms/__tests__/MyComponent.test.tsx

# Entire package
pnpm vitest protocol-designer/

# Watch mode
pnpm vitest --watch app/src/

# Specific project via Make
make test-js-app tests="src/organisms/__tests__/MyComponent.test.tsx"
Linting Specific Files
bash
pnpm eslint path/to/file.tsx
pnpm stylelint path/to/file.module.css
pnpm prettier --check path/to/file.tsx
pnpm prettier --write path/to/file.tsx   # auto-fix

Event Handlers

typescript
import type { MouseEvent } from 'react'

// Named handlers for complex logic
const handleClick = (e: MouseEvent<HTMLButtonElement>): void => {
  e.preventDefault()
  onClick()
}
return <button onClick={handleClick}>Click me</button>

// Direct reference for simple cases
return <button onClick={onClick}>Click me</button>

// Bad — unnecessary wrapper
return <button onClick={() => onClick()}>Click me</button>

Always specify type on buttons in forms:

typescript
<button type="button" onClick={handleAttach}>Attach</button>
<button type="submit">Submit Form</button>

Constants & Magic Numbers

Extract all constants — avoid inline magic numbers:

typescript
// Good
const UNIT_MB = 1024 * 1024
const MAX_FILES = 5

export const FILE_SIZE_LIMITS = {
  pdf: 10 * UNIT_MB,
  csv: 2 * UNIT_MB,
} as const

// Bad
const sizeMB = Math.round(sizeLimit / (1024 * 1024))

Use object lookups for simple mappings instead of switch statements.

Component Architecture

Separate router logic from presentation for testability:

typescript
// Router-aware wrapper
function AppWithRouter() {
  const location = useLocation()
  return <AppContent isOnChatPage={location.pathname === '/chat'} />
}

// Pure presentation (easily testable)
function AppContent({ isOnChatPage }: { isOnChatPage: boolean }) {
  return <div>{!isOnChatPage ? <Footer /> : null}</div>
}

Common Pitfalls

  • Do NOT use any — strict TypeScript is enforced
  • Do NOT use default exports (except config files and stories)
  • Do NOT use class components — functional only
  • Do NOT use arrow functions for component definitions
  • Do NOT use implicit truthiness for null checks — use explicit != null
  • Do NOT import the full lodash package — use granular imports
  • Do NOT use inline styles in components
  • Do NOT use querySelector in tests
  • Do NOT introduce new styled-components — use CSS Modules
  • Do NOT import up the atomic design hierarchy (atoms ← molecules ← organisms ← pages)
  • Do NOT skip afterEach(() => vi.clearAllMocks()) in test suites
  • Do NOT use semicolons (Prettier removes them)
  • Do NOT use console.log or debugger in committed code
  • Do NOT omit curly braces for control statements — ESLint curly rule enforces braces for all if, else, for, while, and do blocks
  • Do NOT use primitives (primitives are located in components/src/primitives) for new component - use HTML 5 tags and CSS Modules
  • Do NOT use margins to create a layout in a component - use padding and gap
  • Do NOT use a conditional statement for aria-label
  • Do NOT use a nested ternary in non-component render code

© Opentrons, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .cursor/skills/opentrons-typescript of Opentrons/opentrons.

Open the folder on GitHubat commit adb4970

Compare with similar skills

Opentrons Typescript next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Opentrons Typescript compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Opentrons Typescript this skillOpentrons/opentrons523—~3.7kAutomated safety check: PassApache-2.0
OpenTUI Terminal Interfacescline/cline70k—~1.9kAutomated safety check: PassApache-2.0
Pnpm Engineteambit/bit18k—~1.9kAutomated safety check: PassCustom licence
Qovery Console StandardsQovery/console227—~924Automated safety check: PassMIT
React Render Types CompositionHorusGoul/eslint-plugin-react-render-types111—~1.1kAutomated safety check: PassMIT
Trigger Getting StartedVladSez/easy-invoice-pdf1.1k—~2kAutomated safety check: NotesAGPL-3.0

Similar skills

  • Helps build terminal user interfaces with OpenTUI using its core imperative API or its React and Solid reconcilers, with references for layout, keyboard, animation and testing.

    70k GitHub stars~1.9k tokensUpdated today
    DevelopmentAuto-check passed
  • Pnpm Engine

    teambit/bit

    Work on the pnpm Rust engine (@pnpm/napi, the pacquet crates) that bit install runs through.

    18k GitHub stars~1.9k tokensUpdated today
    DevelopmentAuto-check passed
  • Qovery Console coding standards, architecture guidelines, naming conventions, testing practices, and development workflows.

    227 GitHub stars~924 tokensUpdated today
    DevelopmentAuto-check passed
  • React Render Types Composition

    HorusGoul/eslint-plugin-react-render-types

    Composition patterns for building React components with @renders type annotations from eslint-plugin-react-render-types.

    111 GitHub stars~1.1k tokensUpdated 2 mo ago
    Frontend & DesignAuto-check passed
  • Trigger Getting Started

    VladSez/easy-invoice-pdf

    Bootstrap Trigger.dev into an existing project from scratch: authenticate the CLI, install @trigger.dev/sdk and @trigger.dev/build, write trigger.config.ts with the project ref and task dirs…

    1.1k GitHub stars~2k tokensUpdated today
    DevelopmentAuto-check: notes
  • Safe Element Comparison

    seasonedcc/remix-forms

    Maintain element type comparison safety in remix-forms. An agent skill from seasonedcc/remix-forms.

    514 GitHub stars~1.8k tokensUpdated 5 mo ago
    Frontend & DesignAuto-check passed

More from Opentrons/opentrons

All 17 skills in this repo
  • AI Client

    Opentrons/opentrons

    Conventions for the opentrons-ai-client React/TypeScript frontend — project structure, API integration, state management (Jotai), feature flags, types, and testing.

    523 GitHub stars~1.6k tokensUpdated today
    Auto-check passed
  • AI Server

    Opentrons/opentrons

    Conventions for the opentrons-ai-server FastAPI service — project structure, uv dependency management, settings, testing, Docker, and deployment.

    523 GitHub stars~2.5k tokensUpdated today
    Auto-check: notes
  • Analyses Snapshot Testing

    Opentrons/opentrons

    Conventions for the analyses snapshot testing framework in analyses-snapshot-testing/.

    523 GitHub stars~1.7k tokensUpdated today
    Auto-check passed
  • CSS Modules

    Opentrons/opentrons

    CSS Modules conventions, Stylelint rules, design tokens (spacing, colors, typography, border-radius), and patterns for the Opentrons monorepo.

    523 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Docs

    Opentrons/opentrons

    Authoring and styling guidelines for the Opentrons /docs MkDocs project.

    523 GitHub stars~2.8k tokensUpdated today
    Auto-check passed
  • E2E Testing

    Opentrons/opentrons

    E2E testing conventions for Protocol Designer and Labware Library using Playwright + pytest in e2e-testing/.

    523 GitHub stars~3k tokensUpdated today
    Auto-check: notes

Works with

Questions about Opentrons Typescript

What does Opentrons Typescript do?

TypeScript conventions, React patterns, testing, styling, and import rules for the Opentrons monorepo JS/TS packages. Opentrons Typescript is an agent skill from Opentrons/opentrons. TypeScript conventions, React patterns, testing, styling, and import rules for the Opentrons monorepo JS/TS packages.

When should I use Opentrons Typescript?

Opentrons Typescript fits situations like: working with TypeScript; React files in app/; step-generation/; protocol-designer/.

How do I install Opentrons Typescript in Claude Code?

Run `npx skills add Opentrons/opentrons --skill opentrons-typescript -a claude-code`. Or copy the skill folder (.cursor/skills/opentrons-typescript in Opentrons/opentrons) into .claude/skills/opentrons-typescript in your project. Claude Code loads it when a task matches its description.

How do I install Opentrons Typescript in Codex?

Run `npx skills add Opentrons/opentrons --skill opentrons-typescript -a codex`. Or copy the skill folder (.cursor/skills/opentrons-typescript in Opentrons/opentrons) into .agents/skills/opentrons-typescript in your project. Codex loads it when a task matches its description.

Can I use Opentrons Typescript in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Opentrons/opentrons --skill opentrons-typescript -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/opentrons-typescript, .gemini/skills/opentrons-typescript, .github/skills/opentrons-typescript and .opencode/skills/opentrons-typescript in your project.

What does Opentrons Typescript need to run?

Going by SKILL.md and its folder, Opentrons Typescript needs the command-line tools its instructions call (make, pnpm and tsc). Our summary lists: Python 3; Node.js.

Does Opentrons Typescript access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Opentrons Typescript safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Opentrons Typescript use?

Opentrons Typescript is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Opentrons Typescript use?

About 3.7k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Opentrons Typescript?

Skills that share tags, products or a category with Opentrons Typescript: OpenTUI Terminal Interfaces (cline/cline, 70k stars), Pnpm Engine (teambit/bit, 18k stars), Qovery Console Standards (Qovery/console, 227 stars) and React Render Types Composition (HorusGoul/eslint-plugin-react-render-types, 111 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Opentrons Typescript?

Opentrons (a GitHub organization) maintains it in Opentrons/opentrons, which has 523 GitHub stars. The repository holds 17 skills in this directory. The repository was last updated on October 9, 2026.

Source: Opentrons/opentrons on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.