Components / Molecular & cellular

DNA helix

Type a sequence and get its double helix, with every base paired to its complement. Built procedurally, so there is no model to download.

Installation

bunx shadcn@4.22.1 add https://organui.com/r/dna-helix.json

Or by name: bunx shadcn@4.22.1 add @organui/dna-helix.

The source installs into your components directory and adds three.js, plus shadcn's alert, button and tooltip. Its buttons are composed with Base UI's render prop, so it needs one of shadcn's Base UI styles, such as base-nova; on a Radix style its buttons do nothing. It uses your theme tokens and installs no global styles.

View registry item JSON

Usage

"use client"
import { useState } from "react"
import { DnaHelix } from "@/components/dna-helix"

export function GenePanel() {
  const [selected, select] = useState<number | null>(null)
  return (
    <DnaHelix
      sequence="ATGCGTACCTGAGCTTAACG"
      selectedIndex={selected}
      onSelectionChange={select}
    />
  )
}

sequence is one strand read 5′ to 3′; whitespace and case are ignored, and any letter other than A, C, G or T shows a message instead of a helix. Selection is controlled: pass selectedIndex, counted from 0 at the 5′ end, and update it from onSelectionChange, which also passes the pair with its partner base and hydrogen bond count. dnaBasePairs(sequence) returns the same pairs without rendering.

Geometry and behaviour

The helix is right-handed B-DNA: 3.38 Å rise and 34.3° twist per pair, about 10.5 pairs a turn, with phosphates 9 Å from the axis and the backbones closer on one side to leave the minor and major grooves. Bases are coloured A red, T blue, G green and C yellow, the same as nucleotides in the molecule viewer. It is a schematic: base geometry, sugars and sequence-dependent shape are not modelled.

The helix turns slowly about its axis until the user pauses it, moves the camera, or prefers reduced motion; pass autoRotate={false} to keep it still. Click a base pair, or use the strands below the stage, which are one tab stop moved with the arrow keys, Home and End. Drag or the arrow keys rotate; scroll, pinch, plus and minus zoom.

WebGL is required. Pass strands={false} to hide the sequence strip and controls={false} to hide the buttons; the ref exposes zoom, rotate and reset.