npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@billdestein/react-better-frames

v0.0.20

Published

React Better Frames

Readme

react-better-frames

A user-friendly windowing system for React applications.

Demo

An easy-to-understand interactive demo can be found here:

https://billdestein.github.io/react-better-frames-demo/

The source code for the demo is here:

https://github.com/billdestein/react-better-frames-demo

Key Concepts

The following paragraphs will walk you through developing a very simple windowed React application called 'Hello'.

Key concepts include the container div, the Canvas, the Frame and the Applet.

The container div is what it sounds like. It's a generic div, typically a large div, that will contain some number of Frames. The container div must be assigned an Id that is globally unique.

Canvas is a Typescript class. An application typically creates a single instance of the Canvas class. The Canvas constructor takes a single argument, and that is the ID of the container div. Once the Canvas instance is create, it is used to add frames to the container div, remove frames from the container div, and to manage many other features.

A frame is simply an HTML div that supports dragging, resizing, and restacking operations. All of these operations are controlled through user mouse interactions. The operations are implemented using direct DOM manipulation. React is unaware that these operations are happening. So there is no unwanted re-rendering of React components. And there is no loss of state caused by re-rendering.

An applet is a react application running in a frame. Each applet has its own user experience and its own business logic. React-better-frames provides strong isolation among applets. This isolation allows applet developers to work largely independently. In cases where applets need to cooperate, that can be accomplished through message passing, callbacks, and singletons.

Getting Started

This guide will walk you through setting up a new React project configured with TypeScript using the officially supported create-react-app tool.

Prerequisites

Make sure you have Node.js installed on your system, which includes npm (Node Package Manager).

Step 1: Create a New Project

Using your terminal, navigate to the directory where you want to create your project and run the following command. The key is to include the --template typescript flag.

    npx create-react-app hello-app --template typescript

Step 2: Wait for Installation

The command will create a new directory, download all necessary dependencies (React, ReactDOM, TypeScript, Webpack, Babel, etc.), and set up the project structure. This might take a few minutes.

Step 3: Navigate to Your Project Directory

Using your terminal, change your current directory to your new project folder:

   cd hello-app

Step 4: Project Structure

At this point, your project structure will look similar to a standard JavaScript React app, but with some key differences:

hello-app/
├── node_modules/
├── public/
├── src/
│   ├── App.css
│   ├── App.tsx          <-- TypeScript React component file
│   ├── App.test.tsx     <-- TypeScript test file
│   ├── index.css
│   ├── index.tsx        <-- Entry point of your app, uses TypeScript
│   ├── react-app-env.d.ts <-- TypeScript declaration file
│   ├── reportWebVitals.ts
│   └── setupTests.ts
├── .gitignore
├── package.json
├── package-lock.json
└── tsconfig.json        <-- TypeScript configuration file

Note 1: The .tsx extension indicates a file containing TypeScript code and JSX.

Note 2: The tsconfig.json file contains all the compiler options for your TypeScript project. You are now ready to start building your application with the benefits of TypeScript's static type checking!

Creating Your First Applet

Steo 1: Install NPM packages

Using your terminal, cd to your hello-app directory, and run:

    npm install @billdestein/react-better-frames styled-components

Navigate to the src directory:

    cd src

Create an empty Hello.tsx file:

    touch Hello.tsx    

Step 2: Edit Hello.tsx

Using your favorite code editor, open the newly create Hello.tsx file. Paste the following code into the file and save the file.

import React from 'react'
import { Canvas, Frame, FrameProps } from '@billdestein/react-better-frames'
import styled from 'styled-components'

const HelloApplet = (frameProps: FrameProps) => {
  const { canvas, geometry, message } = frameProps
  
  return (
    <Frame
      buttons={[]}
      canvas={canvas as Canvas}
      geometry={geometry}
      onResize={() => {}}
      title={message.title}
    >
      <p>Hello</p>
    </Frame>
  )
}

const app = (canvas: Canvas) => {
  canvas.addComponent(HelloApplet, { title: 'My First Applet' })
  canvas.addComponent(HelloApplet, { title: 'My Second Applet' })
}

export const Hello = () => {
  const ready = () => {
    const element = document.getElementById('container-id')
    const canvas = new Canvas(element)
    app(canvas)
  }

  return (
    <div ref={ready} style={{ height: '100vh' }} id="container-id"/>
  );
}

Step 3: Edit App.tsx

Again, using your favorite code editor, open the App.tsx file. Replace the content of the file with the code here:

import React from 'react';
import './App.css';
import { Hello } from './Hello'

function App() {
  return (
    <Hello/>
  );
}

export default App;

Start the Development Server

Navigate to the root of your project:

    cd ..

and then:

    npm run start

This command will open a window in your default browser, pointing to http://localhost:3000. The web page should look like this:

Screenshot

Understanding Hello.tsx

Here we will examine the file Hello.tsx. We will start at the bottom of the file and progress upward.

The Hello function component

The purpose of the Hello function is to:

  1. Render the container div.
  2. Wait until the container div has been rendered into the DOM.
  3. Create an instance of the Canvas class (passing the id of the container div).
  4. Call the app function, passing the newly created Canvas object.

Note that there are multiple ways to wait for a React component to be fully rendered. The authors prefer the use of callback refs -- which is now considered an anti-pattern. The more mainstream approach is to use React hooks useEffect, useRef and useState.

The app function

The app function performs application-wide initialization, and then uses the Canvas object to create frames. Note that frames can be created and destroyed at any time during the app lifecycle. They don't need to be created at app initialization time.

The HelloFrame function component

The HelloFrame function component implements what we call a "frame". Each frame can have its own user experience and its own business logic. An app may have many different types of frames. Note that a single frame can instantiate one or more child frames, and communicate with them using message passing and callbacks.