Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yisar/fre
:ghost: Tiny Concurrent UI library with Fiber.
https://github.com/yisar/fre
fiber fre hook hooks jsx keyed-reconcilation-algorithm react-hooks react-like reconcilation reconciliation-algorithm vdom vdom-library
Last synced: 3 months ago
JSON representation
:ghost: Tiny Concurrent UI library with Fiber.
- Host: GitHub
- URL: https://github.com/yisar/fre
- Owner: frejs
- License: mit
- Created: 2018-07-28T06:46:46.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-04-04T23:38:29.000Z (7 months ago)
- Last Synced: 2024-05-30T02:12:23.826Z (6 months ago)
- Topics: fiber, fre, hook, hooks, jsx, keyed-reconcilation-algorithm, react-hooks, react-like, reconcilation, reconciliation-algorithm, vdom, vdom-library
- Language: TypeScript
- Homepage: https://fre.deno.dev
- Size: 6.22 MB
- Stars: 3,701
- Watchers: 39
- Forks: 349
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-list - fre
- awesome-list - fre
README
Fre
π» Tiny Concurrent UI library with Fiber.
- **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 longest-common-subsequence algorithm, It supported keyed, pre-process.
- **Do more with less** β After tree shaking, project of hello world is only 1KB, but it has most features, virtual DOM, hooks API, Fragments, Fre.memo and so on.
### Contributors
### Usage
```shell
yarn add fre
``````js
import { render, useState } from 'fre'function App() {
const [count, setCount] = useState(0)
return <>
{count}
setCount(count + 1)}>+
>
}render(, document.body)
```### Hooks API
- [useState](https://github.com/yisar/fre#usestate)
- [useEffect](https://github.com/yisar/fre#useeffect)
- [useReducer](https://github.com/yisar/fre#usereducer)
- [useLayout](https://github.com/yisar/fre#uselayout)
- [useCallback](https://github.com/yisar/fre#usecallback)
- [useMemo](https://github.com/yisar/fre#usememo)
- [useRef](https://github.com/yisar/fre#useref)
#### 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
```js
function App() {
const [up, setUp] = useState(0)
const [down, setDown] = useState(0)
return (
<>
{up}
setUp(up + 1)}>+
{down}
setDown(down - 1)}>-
>
)
}
```#### useReducer
`useReducer` and `useState` are almost the sameοΌbut `useReducer` needs a global reducer
```js
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}
dispatch({ type: 'up' })}>+
dispatch({ type: 'down' })}>-
>
)
}
```#### 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
``````js
function App({ flag }) {
const [count, setCount] = useState(0)
useEffect(() => {
document.title = 'count is ' + count
}, [flag])
return (
<>
{count}
setCount(count + 1)}>+
>
)
}
```If it returns a function, the function can do cleanups:
```js
useEffect(() => {
document.title = 'count is ' + count
return () => {
store.unsubscribe()
}
}, [])
```#### useLayout
More like useEffect, but useLayout is sync and blocking UI.
```js
useLayout(() => {
document.title = 'count is ' + count
}, [flag])
```#### useMemo
`useMemo` has the same rules as `useEffect`, but `useMemo` will return a cached value.
```js
const memo = (c) => (props) => useMemo(() => c, [Object.values(props)])
```#### useCallback
`useCallback` is based `useMemo`, it will return a cached function.
```js
const cb = useCallback(() => {
console.log('cb was cached.')
}, [])
```#### useRef
`useRef` will return a function or an object.
```js
function App() {
useEffect(() => {
console.log(t) // { current:t}
})
const t = useRef(null)
returnt
}
```If it uses a function, it can return a cleanup and executes when removed.
```js
function App() {
const t = useRef((dom) => {
if (dom) {
doSomething()
} else {
cleanUp()
}
})
return flag && I will removed
}
```
### Fragments```js
// fragment
function App() {
return <>{something}>
}
// render array
function App() {
return [a, b, c]
}
```### jsx2
```js
plugins: [
[
'@babel/plugin-transform-react-jsx',
{
runtime: 'automatic',
importSource: 'fre',
},
],
]
```### Compare with other frameworks
The comparison is difficult because the roadmap and trade-offs of each framework are different, but we have to do so.
- react
React is the source of inspiration for fre. Their implementation and asynchronous rendering are similar. The most amazing thing is **concurrent mode**, which means that react and fre have the same roadmap -- **Exploring concurrent use cases**.
But at the same time, fre has obvious advantages in reconciliation algorithm and bundle size.
- vue / preact
To some extent, vue and preact are similar. They have similar synchronous rendering, only the API is different.
The reconciliation algorithm of fre is similar to vue3, but the biggest difference is that vue/preact do not support concurrent mode, this means that the roadmap is totally different.
| framework | concurrent | offscreen | reconcilation algorithm | bundle size |
| --------- | ---------- | --------- | ----------------------- | ----------- |
| fre2 | β | β | β β β β | 2kb |
| react18 | β | β | β β | 43kb |
| vue3 | Γ | x | β β β β β | 33kb |
| preactX | Γ | x | β β β | 4kb |#### License
MIT @yisar
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fyisar%2Ffre.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fyisar%2Ffre?ref=badge_large)