https://github.com/interaapps/puls
(WIP) reactive js/ts library
https://github.com/interaapps/puls
Last synced: about 1 month ago
JSON representation
(WIP) reactive js/ts library
- Host: GitHub
- URL: https://github.com/interaapps/puls
- Owner: interaapps
- Created: 2025-02-10T02:03:43.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-16T20:16:34.000Z (2 months ago)
- Last Synced: 2025-12-20T11:02:15.415Z (2 months ago)
- Language: TypeScript
- Homepage: https://go.intera.dev/puls-example
- Size: 241 KB
- Stars: 3
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# PULS
```js
import { html, appendTo, state } from 'pulsjs'
const name = state('John')
appendTo(document.body, html`
Hello ${name}!
`)
```
Puls is a reactive web framework that uses the DOM directly.
It is inspired by Svelte and Vue. Puls is designed to be simple and fast. It is a great choice for small to medium-sized projects.
**No compiler is required** but if you want, there are .puls component files or JSX support.
## Installation
```bash
npm install pulsjs
```
### Create with Vite
Create a typescript or javascript project with PulsJS and Vite
```bash
npm create pulsjs@latest my-app-name
```
### ESM import in browser
```html
import { html, appendTo, state } from 'https://cdn.skypack.dev/pulsjs'
...
```
## Feature overview
- Puls uses the DOM directly (no virtual DOM)
- Reactive state
- Computed values
- Components
- Control flow
- Event handling
- Bindings
## Hooks (state)
```js
import { state, computed, watch, html, appendTo } from 'pulsjs'
const name = state('John')
const computedValue = computed(() => `I'm happy that you are named ${name.value}`)
watch([name], () => {
console.log('Name changed')
})
appendTo(document.body, html`
Hello ${name}!
${computedValue}
`)
```
### Deep tracking
```js
import { track, state } from 'pulsjs'
const hello = state({
hello: 'World',
world: 'example'
}, { deep: true })
// only refreshes when hello changes
watch([track(() => hello.value.hello)], () => {
console.log('Hello changed')
})
```
## Components
### Functions
```js
import { html } from 'pulsjs'
function ExampleComponent({ example }) {
return html`
Example component ${example}
`
}
html`
<${ExampleComponent} example="hello world" />
`
```
#### Function Components Life-Cycle hooks
```ts
import {defineEmits, defineProps, defineSlot, html, onMounted} from "pulsjs";
function ExampleComponent() {
const props = defineProps<{
example: string;
}>()
const emit = defineEmits()
const slot = defineSlot()
onMounted(() => {
console.log('Mounted')
})
onUnmounted(() => {
console.log('Unmounted')
})
return html``
}
```
### Class components
```js
import { html } from 'pulsjs'
class ExampleComponent extends PulsComponent {
example = state('val')
setup() {
console.log('Setup')
}
render() {
return html`
Example component ${this.example}
`
}
}
registerComponent('example-component', ExampleComponent)
// Typescript
@CustomElement('example-component')
export class ExampleComponent extends PulsComponent {}
const a = state('test')
html`
<${ExampleComponent} example=${a} />
`
```
### Using Web-Components outside of Puls
```js
export class ExampleComponent extends PulsComponent {
test = state('hello')
exampleObject = state({})
// ...
}
registerComponent('example-component', ExampleComponent)
document.body.innerHTML = `
`
```
# Control flow
```js
import { html, appendTo, state, computed } from 'pulsjs'
const counter = state(1)
html`
${computed(() =>
counter.value === 1 ? html`
Value is 1` :
counter.value === 2 ? html`Value is 2` :
html`Value is something else`
)}
counter.value === 1}>
Value is 1
counter.value === 1}>
Value is 2
Value is something else
counter.value++}>Increment ${counter}
`
```
## Extensions
### Puls Component Files (pulsjs-compiler)
Example `ExampleComponent.puls`
```svelte
import { state } from 'pulsjs'
const name = state('John Doe');
${name}
```
[More Information](https://github.com/interaapps/puls/blob/main/packages/puls-compiler/README.md)
### SCSS
```bash
npm install pulsjs-scss
```
```js
import { PulsComponent, CustomElement, html } from 'pulsjs'
import { scss } from 'pulsjs-scss'
export class ExampleComponent extends PulsComponent {
render() {
return html`
example
`
}
styles() {
return scss`
example {
color: red;
}
`
}
}
```
### JSX
```jsx
export function Test() {
const name = state('John')
return (
{name}
name.value = 'test'}>Click me
)
}
```
### Router
```bash
npm install pulsjs-router
```
```js
import { PulsComponent, CustomElement, html } from 'pulsjs'
import { Router } from 'pulsjs-router'
const router = new Router([
{
path: '/',
name: 'home',
view: () => html`
Router Works!
`
},
{
path: '/test',
name: 'test',
view: () => html`
Router page 2!
`
},
{
path: '/*',
name: '404',
view: () => html`
404
`
}
// Also supports nested routes with children and layouting
])
appendTo(document.body, html`
${router.link}
<${router.link} to=${{name: 'home'}}>Home${router.link}>
<${router.link} to="/test">Test Page${router.link}>
`)
router.init()
```
## Contributing
Use pnpm
### Build
```bash
pnpm run build
```
### Test
```bash
pnpm test
```