Socket
Book a DemoInstallSign in
Socket

fre

Package Overview
Dependencies
Maintainers
0
Versions
220
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fre

Tiny Concurrent UI library with Fiber.

2.8.3
latest
Source
npmnpm
Version published
Weekly downloads
193
-58.41%
Maintainers
0
Weekly downloads
 
Created
Source

fre logo

Fre

👻 Tiny Concurrent UI library with Fiber.

GitHub License Build Status Code Coverage npm-v npm-d brotli

  • Concurrent Mode — This is an amazing idea, which implements the coroutine scheduler in JavaScript, it also called Time slicing.

  • Keyed reconcilation algorithm — Fre has a minimal diff algorithm, It supported keyed, pre-process, offscreen rendering and hydrate.

  • Do more with less — Fre get the tiny size, but it has most features, virtual DOM, hooks API, Suspense, Fragments, Fre.memo and so on.

Contributors

Usage

yarn add fre
import { render, useState } from 'fre'

function App() {
  const [count, setCount] = useState(0)
  return <>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
    </>
}

render(<App/>, document.body)

Features

Hooks API

useState

useState is a base API, It will receive initial state and return an Array

You can use it many times, new state is available when component is rerender

function App() {
  const [up, setUp] = useState(0)
  const [down, setDown] = useState(0)
  return (
    <>
      <h1>{up}</h1>
      <button onClick={() => setUp(up + 1)}>+</button>
      <h1>{down}</h1>
      <button onClick={() => setDown(down - 1)}>-</button>
    </>
  )
}

useReducer

useReducer and useState are almost the same,but useReducer needs a global reducer

function reducer(state, action) {
  switch (action.type) {
    case 'up':
      return { count: state.count + 1 }
    case 'down':
      return { count: state.count - 1 }
  }
}

function App() {
  const [state, dispatch] = useReducer(reducer, { count: 1 })
  return (
    <>
      {state.count}
      <button onClick={() => dispatch({ type: 'up' })}>+</button>
      <button onClick={() => dispatch({ type: 'down' })}>-</button>
    </>
  )
}

useEffect

It is the execution and cleanup of effects, which is represented by the second parameter

useEffect(f)       //  effect (and clean-up) every time
useEffect(f, [])   //  effect (and clean-up) only once in a component's life
useEffect(f, [x])  //  effect (and clean-up) when property x changes in a component's life
function App({ flag }) {
  const [count, setCount] = useState(0)
  useEffect(() => {
    document.title = 'count is ' + count
  }, [flag])
  return (
    <>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
    </>
  )
}

If it returns a function, the function can do cleanups:

useEffect(() => {
  document.title = 'count is ' + count
  return () => {
    store.unsubscribe()
  }
}, [])

useLayout

More like useEffect, but useLayout is sync and blocking UI.

useLayout(() => {
  document.title = 'count is ' + count
}, [flag])

useMemo

useMemo has the same rules as useEffect, but useMemo will return a cached value.

const memo = (c) => (props) => useMemo(() => c, [Object.values(props)])

useCallback

useCallback is based useMemo, it will return a cached function.

const cb = useCallback(() => {
  console.log('cb was cached.')
}, [])

useRef

useRef will return a function or an object.

function App() {
  useEffect(() => {
    console.log(t) // { current:<div>t</div> }
  })
  const t = useRef(null)
  return <div ref={t}>t</div>
}

If it uses a function, it can return a cleanup and executes when removed.

function App() {
  const t = useRef((dom) => {
    if (dom) {
      doSomething()
    } else {
      cleanUp()
    }
  })
  return flag && <span ref={t}>I will removed</span>
}

useContext

import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Button />
    </ThemeContext.Provider>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button class={className}>
      {children}
    </button>
  );
}

Suspense

const Hello = lazy('./hello.js')

export function App() {
  return (
    <div>
      <Suspense fallback={<div>loading...</div>}>
        <Hello />
        <div>world!</div>
      </Suspense>
    </div>
  )
}

Fragments

// fragment
function App() {
  return <>{something}</>
}
// render array
function App() {
  return [a, b, c]
}

jsx2

plugins: [
  [
    '@babel/plugin-transform-react-jsx',
    {
      runtime: 'automatic',
      importSource: 'fre',
    },
  ],
]

License

MIT @yisar

FOSSA Status

Keywords

fre

FAQs

Package last updated on 05 Aug 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

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.