Source: https://docs.nitro.bio/ # React components for life science Build sequence interfaces, laboratory plate editors, and molecular structure views with Nitro Bio's published React packages. Try the interactive examples, then bring the same components into your application. ## Choose a component | Package | Use it for | Documentation | | ----------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `@nitro-bio/sequence-viewers` 2.1.0 | Residue-level sequences, linear overviews, circular maps, and optional browser alignment | [Sequence Viewer](https://docs.nitro.bio/SequenceViewer), [Linear Viewer](https://docs.nitro.bio/LinearViewer), [Circular Viewer](https://docs.nitro.bio/CircularViewer) | | `@nitro-bio/platemap` 2.0.3 | Layered plate layouts, well selection, annotations, and CSV/JSON workflows | [Platemap](https://docs.nitro.bio/Platemap) | | `@nitro-bio/molstar-easy` 0.0.19 | Interactive molecular structures with labels and residue colors | [Molecule Viewer](https://docs.nitro.bio/MoleculeViewer) | ## Start with a sequence viewer Install the package alongside React and React DOM: ```sh pnpm add @nitro-bio/sequence-viewers@^2.1.0 ``` Import the compiled stylesheet once in your application entry point. In a Next.js App Router project, use your root layout: ```tsx import "@nitro-bio/sequence-viewers/styles.css"; ``` Sequence Viewers 2 supports React 18.2+ and React 19. It ships its own component CSS, so your application does not need Tailwind. In Next.js, interactive examples that use React state belong in a component marked `"use client"`. Continue with the [Sequence Viewer example](https://docs.nitro.bio/SequenceViewer#example) for controlled selection, annotations, and alignment. ## What changed in version 2 Sequence Viewer styles are isolated from the host page and use `--nsv-color-sequences-*` theme variables. Validation recovers locally by default, and browser alignment is an explicit opt-in. See the [migration notes](https://docs.nitro.bio/SequenceViewer#upgrading-from-version-1) before updating an existing integration. Platemap now uses a layer-based state model shared by `Plate` and `PlateControls`. Its examples use the current published package and public stylesheet. See the [Platemap quick start](https://docs.nitro.bio/Platemap#quick-start). ## Source and support * [Sequence Viewers source and releases](https://github.com/nitro-bio/sequence-viewers) * [Platemap source](https://github.com/nitro-bio/nitro-bio-apps/tree/main/packages/platemap) * [Molecule Viewer source](https://github.com/nitro-bio/molstar-easy) * [Docs source](https://github.com/nitro-bio/nitro-bio-apps/tree/main/apps/docs) Each package has its own license; check its documentation before integrating. Send documentation questions to . ## Documentation for tools and agents Use the [Markdown index](https://docs.nitro.bio/llms.txt) for pages with code examples and API guidance, without rendered demo output. A [combined reference](https://docs.nitro.bio/llms-full.txt) is also available. These files are generated from the same source as this website. --- Source: https://docs.nitro.bio/SequenceViewer # Sequence Viewer Explore sequences one residue at a time, select regions, add annotations, and compare aligned rows. This page uses `@nitro-bio/sequence-viewers` **2.1.0**, compatible with React 18.2+ and React 19. [View source](https://github.com/nitro-bio/sequence-viewers/blob/v2.1.0/src/components/Ariadne/SequenceViewer/SequenceViewer.tsx) · [Read as Markdown](https://docs.nitro.bio/SequenceViewer.md) ## Installation ```sh pnpm add @nitro-bio/sequence-viewers@^2.1.0 ``` Import the public stylesheet once from your application entry point or Next.js root layout: ```tsx import "@nitro-bio/sequence-viewers/styles.css"; ``` The stylesheet contains the component styles and does not reset your host page. Tailwind is optional. The supported browser floor is Safari 16.4, Chrome 111, and Firefox 128. ## Quick start This complete client component uses internal selection and default styling: ```tsx "use client"; import { SequenceViewer } from "@nitro-bio/sequence-viewers"; import "@nitro-bio/sequence-viewers/styles.css"; export default function SequenceExample() { return ; } ``` Use the complete [Next.js App Router example](https://github.com/nitro-bio/sequence-viewers/tree/v2.1.0/examples/next) or [Vite example](https://github.com/nitro-bio/sequence-viewers/tree/v2.1.0/examples/vite) for a runnable application. Both are built and tested against the packed npm artifact. The Next.js example places the viewer in a client component and imports the CSS in the root layout. ## Example Drag across either row or click the coding-region annotation. These rows differ by one base. To see how gaps bring shifted sequences into alignment, try the [alignment demo](https://docs.nitro.bio/SequenceViewer#browser-alignment) below. ## Browser alignment These synthetic DNA sequences share a common backbone. The second sequence adds `GGA`, and the third is missing four bases. Before alignment, the remaining bases appear shifted. Click **Align** to insert gaps (`-`) and bring the matching regions into the same columns. **Reset alignment** restores the original inputs so you can compare the result. Alignment is disabled by default in the package; this demo enables it from the start. Pass `enableAlignment` and use `setSequences` to apply the result: ```tsx { setSequences(alignedSequences); setSelection(null); }} selection={selection} setSelection={setSelection} enableAlignment alignmentConfig={{ debug: false }} /> ``` Alignment changes column coordinates. A successful alignment clears selection owned internally by the viewer. Controlled applications must clear or remap their selection in `setSequences`, as this demo does, and every application must clear or remap annotations whose coordinates changed. The first Align action lazily loads MAFFT 7.520 and supporting assets from `https://biowasm.com/cdn/v3`. Sequence alignment runs in a browser worker; sequence input is not uploaded to an alignment service. An enabled viewer without `setSequences` shows a disabled alignment action. Use the [self-hosting setup command and complete recipe](https://github.com/nitro-bio/sequence-viewers/blob/v2.1.0/docs/alignment-self-hosting.md) to prepare the assets in your application. `alignmentConfig.urlCDN` chooses your asset server. Set the configuration before the first alignment; remount the viewer to change an initialized worker's configuration. The [alignment guide](https://github.com/nitro-bio/sequence-viewers/blob/v2.1.0/docs/issue-80/alignment.md) lists the required assets, CSP/CORS setup, and retry behavior. ## Controlled selection Omit `selection` to use the viewer's internal state. An optional `setSelection` callback observes changes. Pass both props to control selection from your application. Explicit `selection={null}` is a controlled empty selection. `charClassName` is optional and has default residue styling. ```tsx "use client"; import { useState } from "react"; import { SequenceViewer, type AriadneSelection, } from "@nitro-bio/sequence-viewers"; export function SequenceExample() { const [sequences, setSequences] = useState([ "ATGCGTACGTTAGCTAGCTA", "ATGCGTACGTTAGCTTGCTA", ]); const [selection, setSelection] = useState(null); return ( ); } ``` `selection` is either `null` or `{ start, end, direction }`. Coordinates are zero-based and selection highlighting includes both endpoints. A range whose `start` is greater than `end` crosses the origin. Share the same complete sequences and selection state when linking this component with a [Linear Viewer](https://docs.nitro.bio/LinearViewer) or [Circular Viewer](https://docs.nitro.bio/CircularViewer). ## Annotations Annotations are optional. Each annotation describes a region and can provide a click handler and a CSS class from your application: ```tsx import type { Annotation } from "@nitro-bio/sequence-viewers"; const annotations: Annotation[] = [ { text: "Coding region", type: "CDS", direction: "forward", start: 6, end: 18, className: "coding-region", }, ]; ``` Pass this array with `annotations={annotations}`. For a controlled viewer, set `onClick: setSelection` on an annotation to select it when clicked. The callback receives the annotation, including its zero-based `start`, inclusive `end`, and `direction`. Version 2.1 fixes the misspelled `diection` field emitted by version 2.0. ## Styling Pass your own class through `containerClassName` and override the public theme tokens. Mirror foreground and background tokens on `.nsv-portal` for the sequence menu, which renders outside the viewer root. ```css .my-sequence-viewer { --nsv-color-sequences-primary: #047857; --nsv-color-sequences-secondary: #4f46e5; --nsv-color-sequences-selection: #059669; --nsv-color-sequences-foreground: #18181b; --nsv-color-sequences-background: #fafafa; --nsv-color-sequences-mismatch: #ef4444; --nsv-color-sequences-gap: #9ca3af; } .nsv-portal { --nsv-color-sequences-foreground: #18181b; --nsv-color-sequences-background: #fafafa; } .coding-region { background: #047857; color: white; } ``` Caller-provided classes are preserved. Define them in plain CSS, or compile them with your own Tailwind setup. You no longer need to scan the package's JavaScript with `@source`. See the [CSS guide](https://github.com/nitro-bio/sequence-viewers/blob/v2.1.0/docs/issue-80/css-isolation.md) for details. ## Validation All three viewers use `validationMode="recover"` by default. Invalid annotations are omitted with a local diagnostic; unsafe sequence shapes show a local placeholder. Valid residues, case, and coordinates are preserved. This is structural validation, not biological alphabet validation. Use `validationMode="strict"` to throw a `ViewerValidationError` for an application error boundary. Empty sequences render an empty state with no active copy, download, or alignment actions. ## Workloads and accessibility The residue viewer renders every displayed column and row; it does not virtualize the DOM. A 100 kb sequence or many sequence rows can create a large amount of browser work. Review the [measured workloads and operating guidance](https://github.com/nitro-bio/sequence-viewers/blob/v2.1.0/docs/limits.md) before choosing it for long sequences or large alignments. The [reproducible benchmark](https://github.com/nitro-bio/sequence-viewers/tree/v2.1.0/benchmarks) records mount and selection times against the packed library. Residue and annotation selection currently use mouse interactions. Metadata controls have accessible names, but the sequence surface is not a complete keyboard or screen-reader editing interface. For keyboard access to a selected range, provide labeled start/end inputs and connect them through controlled selection. See the workload guide for the tested scope and limitations. ## API reference | Prop | Purpose | | -------------------------------------------- | --------------------------------------------------------------------- | | `sequences: string[]` | Sequence rows to render. | | `selection?: AriadneSelection or null` | Controlled selected range; omit for internal state. | | `setSelection?` | Receives changes; the host updates a controlled selection. | | `charClassName?({ base, sequenceIdx })` | Optional callback returning your residue CSS classes. | | `setSequences?` | Receives updated sequences; also required to apply alignment results. | | `annotations?` | Optional `Annotation[]`; omission and an empty array are supported. | | `containerClassName?`, `selectionClassName?` | Style the viewer and selected region. | | `highlightMisalignments?` | Highlight mismatching positions across rows. | | `hideMetadataBar?`, `hideDownloadButton?` | Hide the metadata bar or download action. | | `enableAlignment?`, `alignmentConfig?` | Opt into alignment and configure asset loading. | | `validationMode?` | `"recover"` (default) or `"strict"`. | ## Upgrading from version 1 1. Import `@nitro-bio/sequence-viewers/styles.css` and remove package `@source` scanning. 2. Move viewer theme overrides to `--nsv-color-sequences-*`. Host Tailwind color variables no longer control the library defaults. 3. Add `enableAlignment` if you want the alignment action; `setSequences` alone no longer enables it. 4. Replace deprecated `noValidate` with `validationMode`. Legacy `true` maps to `"recover"`, and explicit `false` maps to `"strict"`; an explicit mode takes precedence. Existing `dist/nitro.css` and `dist/nitro-sequence-viewers.css` imports remain aliases for compatibility. The public `styles.css` entry is recommended for new code. --- Source: https://docs.nitro.bio/LinearViewer # Linear Viewer Display sequence rows as a compact overview with annotations and controlled selection. This example uses `@nitro-bio/sequence-viewers` **2.1.0**. [View source](https://github.com/nitro-bio/sequence-viewers/blob/v2.1.0/src/components/Ariadne/LinearViewer/LinearViewer.tsx) · [Read as Markdown](https://docs.nitro.bio/LinearViewer.md) ## Installation ```sh pnpm add @nitro-bio/sequence-viewers@^2.1.0 ``` Import `@nitro-bio/sequence-viewers/styles.css` once in your application entry point. React 18.2+ and React 19 are supported; Tailwind is optional. See the [shared styling guide](https://docs.nitro.bio/SequenceViewer#styling). ## Linked example Select a region in either viewer. The overview and residue-level view share the same complete sequences, annotations, and selection; slicing the sequence separately would change the coordinate system. ## Code ```tsx "use client"; import { useState } from "react"; import { LinearViewer, SequenceViewer, type AriadneSelection, } from "@nitro-bio/sequence-viewers"; const sequences = [ "ATGC".repeat(30), "ATGC".repeat(12) + "TTAA" + "ATGC".repeat(17), ]; export function LinkedViewers() { const [selection, setSelection] = useState(null); const shared = { sequences, selection, setSelection }; return ( <> ""} highlightMisalignments /> ); } ``` ## Annotations and selection Pass an optional `Annotation[]` through `annotations`. Use the same array in both viewers when you want annotations and selections to stay in sync. Ranges use zero-based coordinates, and selection highlighting includes both endpoints. The `sequenceClassName` callback receives an object: `({ sequenceIdx }) => "my-sequence"`. Use `selectionClassName(selection)` and `mismatchClassName(base)` for custom selection and mismatch styles. Define returned classes in your application stylesheet. ## API reference | Prop | Purpose | | ------------------------------------------- | ----------------------------------------------------- | | `sequences: string[]` | Complete sequence rows in a shared coordinate system. | | `selection`, `setSelection` | Controlled `AriadneSelection` or `null`. | | `annotations?` | Optional annotated regions. | | `containerClassName?`, `sequenceClassName?` | Viewer and row styling. | | `selectionClassName?`, `mismatchClassName?` | Callbacks returning selection and mismatch classes. | | `stackingFn?` | Custom annotation stacking function. | | `onDoubleClick?` | Handle a double-click on the viewer. | | `validationMode?` | `"recover"` (default) or `"strict"`. | Malformed annotations produce a local diagnostic in recovery mode. Prefer `validationMode` over the deprecated `noValidate` prop. Read the [version 2 migration notes](https://docs.nitro.bio/SequenceViewer#upgrading-from-version-1) for styling and validation changes. --- Source: https://docs.nitro.bio/CircularViewer # Circular Viewer Render circular sequences and annotated features, including regions that cross the origin. This page uses `@nitro-bio/sequence-viewers` **2.1.0**. [View source](https://github.com/nitro-bio/sequence-viewers/blob/v2.1.0/src/components/Ariadne/CircularViewer/CircularViewer.tsx) · [Read as Markdown](https://docs.nitro.bio/CircularViewer.md) ## Installation ```sh pnpm add @nitro-bio/sequence-viewers@^2.1.0 ``` Import `@nitro-bio/sequence-viewers/styles.css` once in your application entry point. React 18.2+ and React 19 are supported; Tailwind is optional. ## Compact example ```tsx "use client"; import { useState } from "react"; import { CircularViewer, type AriadneSelection, } from "@nitro-bio/sequence-viewers"; export function CircularExample() { const [selection, setSelection] = useState(null); return ( ); } ``` ## Origin-spanning regions A selection or annotation with `start > end` crosses the origin. Coordinates are zero-based, and selection highlighting includes both endpoints. This example selects from index 240 through the origin to index 30 in a 300-base sequence. Pass the same sequence into a residue-level viewer as `sequences={[sequence]}` and share selection state. Keep the complete sequence in both components so circular ranges retain their coordinates. ## Annotations ```tsx import type { Annotation } from "@nitro-bio/sequence-viewers"; const annotations: Annotation[] = [ { text: "Origin-spanning feature", type: "CDS", direction: "forward", start: 240, end: 30, className: "circular-feature", }, ]; ``` Pass `annotations={annotations}` and define the class in your application: ```css .circular-feature { fill: #047857; color: #047857; } ``` Use the shared [theme tokens](https://docs.nitro.bio/SequenceViewer#styling) through `containerClassName` to match your application. ## API reference | Prop | Purpose | | ------------------------------------- | --------------------------------------------------------------- | | `sequence: string` | A complete circular sequence. | | `selection: AriadneSelection or null` | Controlled selected region. | | `setSelection` | Receives a selected range. | | `annotations?` | Optional annotated regions, including origin-spanning features. | | `containerClassName?` | Viewer class for layout and theme tokens. | | `svgSizePX?`, `svgPadding?` | Set the diagram size and padding. | | `validationMode?` | `"recover"` (default) or `"strict"`. | Use recovery mode to display local diagnostics for malformed input, or strict mode with an error boundary. See the [version 2 migration notes](https://docs.nitro.bio/SequenceViewer#upgrading-from-version-1) for the deprecated `noValidate` mapping and updated stylesheet setup. --- Source: https://docs.nitro.bio/Platemap # Platemap Build interactive laboratory plate layouts with independently editable layers, well selection, annotations, and CSV/JSON workflows. These examples use the published `@nitro-bio/platemap` **2.0.3** package, compatible with React 18.2 and newer versions below React 20. [View source](https://github.com/nitro-bio/nitro-bio-apps/tree/main/packages/platemap) This package is available under [GPL-3.0-or-later](https://github.com/nitro-bio/nitro-bio-apps/blob/main/packages/platemap/LICENSE). For commercial licensing options, contact . ## Installation ```sh pnpm add @nitro-bio/platemap@^2.0.3 ``` Import the public stylesheet once in your application entry point or root layout: ```tsx import "@nitro-bio/platemap/dist/nitro-platemap.css"; ``` ## Quick start `usePlateReducer` provides the shared state and actions for both `Plate` and `PlateControls`. ```tsx "use client"; import { Plate, PlateControls, usePlateReducer } from "@nitro-bio/platemap"; export function PlateEditor() { const reducer = usePlateReducer({ initialPlateSize: 96, initialLayers: [ { id: "00000000-0000-4000-8000-000000000096", name: "Layer 1", annotations: [], }, ], }); return ( <> ); } ``` For server-rendered applications, provide stable initial layer IDs so the server and browser render the same attributes. Select wells, create or rename layers, and switch between the editable flat view and the read-only layers overview. `PlateControls` also provides file import and export. ## Interactive 96-well plate ## Plate sizes Supported sizes are `24`, `48`, `96`, `384`, and `1536`. Set `initialPlateSize` when initializing state, or call `plateActions.setPlateSize` to change it later. ## Layers and annotations Version 2 stores annotations in `plateState.layers`. The active layer is identified by `activeLayerId`; selected and excluded wells remain global across layers. Use `plateActions.setLayerAnnotations(layerId, annotations)` to update a layer. An annotation includes an `id`, `label`, `wells`, and semantic `annotationStyle`: ```tsx import { GREEN_STYLE, type WellAnnotation } from "@nitro-bio/platemap"; const annotations: WellAnnotation[] = [ { id: "00000000-0000-4000-8000-000000000001", label: "Control", wells: [0, 1, 2], annotationStyle: GREEN_STYLE, }, ]; ``` Well indices are zero-based. Use `excelCellToIndex` and `indexToExcelCell` to convert between indices and labels such as `A1`. Preset colors and canonical custom `#RRGGBB` colors are supported. ## Import and export The durable JSON format uses `schemaVersion: 1` and stores `plateSize`, `excludedWells`, and `layers`. Selection, active IDs, and view mode are transient. Use `parsePlateDocument`, `plateStateToDocument`, and `plateDocumentToJSON` for validated document workflows. Tidy CSV import requires `Well` and `Annotation` columns. `Annotation Key` and `Color` are optional, and extra columns can carry flat primitive metadata. The older plate-shaped CSV matrix remains an export format; it is not accepted by the layer importer. ## Upgrading from version 1 Replace flat `wellAnnotations` state with layer annotations and use the shared reducer props shown above. The component stylesheet owns visual classes; customize the semantic `--platemap-*` variables rather than constructing Tailwind classes inside annotation styles. `parsePlateState` can migrate validated legacy flat state. The [package README](https://github.com/nitro-bio/nitro-bio-apps/tree/main/packages/platemap) describes the current state and layer controls. --- Source: https://docs.nitro.bio/MoleculeViewer # Molecule Viewer This example uses `@nitro-bio/molstar-easy` **0.0.19**. Install it via: ```sh pnpm add @nitro-bio/molstar-easy@^0.0.19 ``` The published 0.0.19 release targets React 18 and includes a React 18 JSX runtime. This React 19 docs app applies a [compatibility patch](https://github.com/nitro-bio/nitro-bio-apps/blob/main/patches/%40nitro-bio__molstar-easy%400.0.19.patch) that uses the host React runtime. React 19 integrations need this fix until the package publishes a compatible build. ## Basic Usage ```tsx "use client"; import { useEffect, useState } from "react"; import { MoleculeViewer } from "@nitro-bio/molstar-easy"; export const Demo = () => { const [pdbStrs, setPdbStrs] = useState<[string, string] | null>(null); useEffect(function fetchPDB() { const pdbUrls = [ "https://files.rcsb.org/download/1CRX.pdb", "https://files.rcsb.org/download/1CRN.pdb", ]; Promise.all( pdbUrls.map((url) => fetch(url).then((res) => res.text())), ).then((pdbStrs) => { setPdbStrs([pdbStrs[0], pdbStrs[1]]); }); }, []); return (
{pdbStrs && ( ({ structureString: pdbStr, format: "pdb", // or "mmcif" }))} defaultStructureHexColor="#7279df" backgroundHexColor="#f4f4f4" /> )}
); }; ``` ## With Highlights ```tsx const highlights = [ { label: { text: "Active Site", hexColor: "#881337", scale: 1 }, start: 14, end: 30, }, ]; ; ``` ## With Custom Styling ```tsx ``` ## With Transforms ```tsx import { ModelTransform } from "@nitro-bio/molstar-easy"; const transform: ModelTransform = { position: { x: 10, y: 0, z: 0 }, rotation: { x: 0, y: 45, z: 0 }, // degrees }; ; ``` ## With Custom Per-Residue Colors ```tsx const indexToColor = new Map([ [1, "#ff0000"], [2, "#00ff00"], [3, "#0000ff"], ]); ; ``` ## Advanced: Using the Hook Directly For more control, you can use the `useMolstarViewer` hook directly: ```tsx "use client"; import { useEffect, useRef } from "react"; import { useMolstarViewer, type MoleculePayload, } from "@nitro-bio/molstar-easy"; export const CustomViewer = ({ pdbString }: { pdbString: string }) => { const canvasRef = useRef(null); const parentRef = useRef(null); const { ready, api } = useMolstarViewer("my-viewer-id"); useEffect(() => { if (canvasRef.current && parentRef.current) { api.init(canvasRef.current, parentRef.current, { background: "#f4f4f4", defaultColor: "#94a3b8", }); } }, []); useEffect(() => { if (ready) { const payloads: MoleculePayload[] = [ { structureString: pdbString, format: "pdb", }, ]; api.ensurePayloads(payloads); } }, [ready, pdbString]); return (
); }; ``` ## API Reference ### MoleculeViewer Props * `moleculePayloads`: `(MoleculePayload | null)[]` - Array of molecule structures to display * `className?`: `string` - CSS class for the container * `backgroundHexColor?`: `string` - Background color (default: `#f4f4f4`) * `defaultStructureHexColor?`: `string` - Default structure color (default: `#94a3b8`) * `viewerId?`: `string` - Unique ID for the viewer instance ### MoleculePayload * `structureString?`: `string` - PDB or mmCIF structure data * `format?`: `"pdb" | "mmcif"` - Format of the structure data (default: `"pdb"`) * `highlights?`: `MoleculeHighlight[]` - Residue highlights * `indexToColor?`: `Map` - Custom per-residue colors (residue index → hex color) * `style?`: `{ type: MoleculeStyle, params?: Record }` - Rendering style * `transform?`: `ModelTransform` - Position and rotation transform ### MoleculeHighlight * `label`: `{ text: string, hexColor: string, scale?: number }` - Label configuration * `start`: `number` - Start residue index * `end`: `number` - End residue index * `hidden?`: `true` - Hide this highlight ### ModelTransform * `position`: `{ x: number, y: number, z: number }` - Translation in 3D space * `rotation`: `{ x: number, y: number, z: number }` - Rotation in degrees (Euler angles)