Line-numbered textarea for the web

numbered-textarea

A textarea with line numbers for Web Components, React, and Vue. It keeps native textarea behavior, adds line count ergonomics, and stays easy to style.

Quick Start

vp add numbered-textarea

import { NumberedTextarea } from "numbered-textarea/react";

export function Editor() {
  return (
    <NumberedTextarea
      defaultValue={"const x = 1;"}
      style={{ width: "100%", height: "320px" }}
    />
  );
}

Import only the wrapper you need with framework-specific subpaths.

Vanilla

Web Component

Register once and style it with CSS variables or Shadow parts.

Component

React

Use controlled or uncontrolled state, refs, and line count callbacks.

Wrapper

Vue

Works with `v-model`, template refs, and the same styling surface.

Install

vp add numbered-textarea

Web Component

import { register } from "numbered-textarea/web";

register();
<numbered-textarea
  placeholder="Write some code..."
></numbered-textarea>

React

import { NumberedTextarea } from "numbered-textarea/react";

<NumberedTextarea
  defaultValue="const x = 1;"
  onInput={(value, lineCount) => console.log(lineCount)}
  style={{ width: "100%", height: "300px" }}
/>

Vue

<script setup>
import { NumberedTextarea } from "numbered-textarea/vue";
</script>

<template>
  <NumberedTextarea
    default-value="const x = 1;"
    style="width: 100%; height: 300px"
  />
</template>

Common API

Input Type Notes
value string Controlled content.
defaultValue string Initial content for uncontrolled usage.
placeholder string Shown when the textarea is empty.
readOnly / readonly boolean Prevents editing.
disabled boolean Disables interaction.
wrap off | soft | hard Matches native textarea wrapping behavior.

Events and Refs

Events

Web Component emits nt-input with { value, lineCount }. React and Vue wrappers expose onInput and @input with the same data.

Refs

React refs and Vue template refs expose focus helpers plus access to the underlying custom element and current line count.

Styling

Style all variants with CSS custom properties or direct Shadow DOM part selectors.

.dark-theme {
  --nt-bg: #1e1e1e;
  --nt-color: #d4d4d4;
  --nt-gutter-bg: #252526;
  --nt-gutter-color: #858585;
  --nt-gutter-border: 1px solid #333;
  --nt-border: 1px solid #333;
}

numbered-textarea::part(gutter) {
  background: #e8f0fe;
  color: #1a73e8;
}

Development

Run locally

Use Vite+ for install, build, checks, and tests in this repository.

View repository
vp install
vp test
vp check