New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

opentui-rescript

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

opentui-rescript

ReScript bindings for OpenTUI - Build terminal user interfaces with type-safe functional programming

latest
Source
npmnpm
Version
0.1.1
Version published
Maintainers
1
Created
Source

OpenTUI ReScript Bindings

ReScript bindings for OpenTUI - A TypeScript library for building terminal user interfaces.

Features

Full Type Safety - Leverages ReScript's powerful type system
React Components - All OpenTUI React components available
Hooks Support - Complete bindings for all OpenTUI hooks
Functional Style - Natural functional programming patterns
Pattern Matching - Use ReScript's pattern matching for event handling

Installation

# Install the package
npm install opentui-rescript

# Or with yarn/pnpm/bun
yarn add opentui-rescript
pnpm add opentui-rescript
bun add opentui-rescript

# You also need the peer dependencies
npm install @opentui/core @opentui/react react rescript

Quick Start

// App.res
open OpenTUI

@react.component
let make = () => {
  <Box style={padding: 2, flexDirection: #column}>
    <Text
      content="Hello from ReScript!"
      style={fg: Core.Colors.brightCyan}
    />
  </Box>
}

// Start the app
render(<App />)->ignore

Components

Box

Container component with flexible layout options:

<Box
  title="My Box"
  style={
    border: true,
    borderStyle: #double,
    padding: 2,
    flexDirection: #column,
  }>
  {children}
</Box>

Text

Display styled text:

<Text
  content="Hello World"
  style={
    fg: Core.Colors.green,
    attributes: Core.TextAttributes.bold,
  }
/>

Input

Text input field with event handlers:

<Input
  placeholder="Enter text..."
  value=inputValue
  focused=isFocused
  onInput={value => setInputValue(_ => value)}
  onSubmit={value => handleSubmit(value)}
/>

Select

Dropdown selection component:

let options = [
  {label: "Option 1", value: "1"},
  {label: "Option 2", value: "2"},
]

<Select
  options
  selectedIndex=0
  focused=isFocused
  onChange={(index, option) => handleChange(index, option)}
/>

ScrollBox

Scrollable container:

<ScrollBox
  focused=isFocused
  style={height: 10, overflow: #scroll}>
  {/* Long content */}
</ScrollBox>

ASCIIFont

Large ASCII text rendering:

<ASCIIFont
  text="TITLE"
  font="Standard"
  style={fg: Core.Colors.brightYellow}
/>

Hooks

useKeyboard

Handle keyboard events:

Hooks.useKeyboard(key => {
  switch key.name {
  | Some("up") => moveUp()
  | Some("down") => moveDown()
  | Some("return") => submit()
  | Some("c") when key.ctrl => exit()
  | _ => ()
  }
})

useRenderer

Access the renderer instance:

let renderer = Hooks.useRenderer()

switch renderer {
| Some(r) => // Use renderer
| None => ()
}

useTerminalDimensions

Get terminal size:

let (width, height) = Hooks.useTerminalDimensions()

useResize

Handle terminal resize:

Hooks.useResize((width, height) => {
  Js.log2("Terminal resized to:", (width, height))
})

Custom Hooks

The package includes helpful custom hooks:

// Focus management
let (focusedIndex, isFocused, getFocusedItem) =
  Hooks.useFocusManager(["input1", "input2", "button"])

// Input state management
let (value, handleInput, handleSubmit, clear) =
  Hooks.useInput(~initialValue="", ~onSubmit=submitForm)

// Select state management
let (selectedIndex, handleChange, getSelectedOption) =
  Hooks.useSelect(~options, ~defaultIndex=0)

Styling

Colors

Use predefined colors:

open OpenTUI.Core.Colors

let styles = {
  fg: brightCyan,
  bg: black,
  borderColor: green,
}

Text Attributes

Combine text attributes:

open OpenTUI.Core

let style = {
  attributes: combineAttributes([
    TextAttributes.bold,
    TextAttributes.italic,
    TextAttributes.underline,
  ])
}

Styled Text Functions

Use helper functions for styled text:

open OpenTUI.Core

let styledText = bold(italic(fg(Colors.cyan, "Styled!")))

<Text content=styledText />

Style Record

Complete style options:

let myStyle: OpenTUI.style = {
  // Colors
  fg: "#00ff00",
  bg: "black",

  // Layout
  width: 40,
  height: 10,
  padding: 2,
  margin: 1,

  // Border
  border: true,
  borderStyle: #double,
  borderColor: "blue",

  // Flexbox
  flexDirection: #row,
  justifyContent: #center,
  alignItems: #center,
  gap: 2,

  // Position
  position: #absolute,
  top: 5,
  left: 10,
}

Examples

Counter App

// examples/Counter.res
@react.component
let make = () => {
  let (count, setCount) = React.useState(() => 0)

  Hooks.useKeyboard(key => {
    switch key.name {
    | Some("up") => setCount(prev => prev + 1)
    | Some("down") => setCount(prev => prev - 1)
    | _ => ()
    }
  })

  <Box>
    <Text content={`Count: ${Int.toString(count)}`} />
  </Box>
}

Login Form

See examples/LoginForm.res for a complete login form implementation with:

  • Multiple input fields
  • Focus management
  • Form validation
  • Status messages

Running Examples

# Build the ReScript code
bun run build

# Run examples
bun run example:basic
bun run example:counter
bun run example:login

Type Definitions

The bindings expose all necessary types:

type style = { /* all style properties */ }
type keyInfo = { name: option<string>, ctrl: bool, alt: bool, shift: bool }
type selectOption = { label: string, value: string, disabled?: bool }
type renderer

Development

# Install dependencies
bun install

# Build ReScript code
bun run build

# Watch mode for development
bun run watch

# Clean build artifacts
bun run clean

Project Structure

packages/rescript/
├── src/
│   ├── OpenTUI.res           # Main module
│   ├── OpenTUI_Types.res     # Type definitions
│   ├── OpenTUI_Core.res      # Core utilities
│   ├── OpenTUI_Components.res # React components
│   └── OpenTUI_Hooks.res     # React hooks
├── examples/
│   ├── Basic.res             # Basic example
│   ├── Counter.res           # Counter app
│   └── LoginForm.res         # Login form
├── package.json
├── rescript.json
└── README.md

Tips

  • Pattern Matching: Use ReScript's pattern matching for cleaner event handling
  • Variants: Use polymorphic variants for finite states (focus, status, etc.)
  • Option Types: Safely handle nullable values with option types
  • Records: Use record types for complex configuration objects
  • Pipe Operator: Chain operations with the pipe operator (->)

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

License

MIT - See the main OpenTUI repository for details.

Keywords

rescript

FAQs

Package last updated on 19 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts