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

fullwork

v1.0.7

Published

Mini framework fullstack JavaScript dengan dua mode: Frontend (client-side, routing berbasis JSON) dan Fullstack (client-side + server-side, dengan API & koneksi database generik).

Readme

Fullwork

Mini framework fullstack JavaScript dengan dua mode:

  1. Frontend — starter kit client-side murni. Routing didefinisikan lewat JSON (route.json + template.json), navigasi pakai History API (pushState), CSS di-inject ke <style> di <head>, dan JS developer di-import otomatis lewat MutationObserver yang mengawasi atribut data-js pada <main>.
  2. Fullstack — semua fitur mode Frontend, ditambah server (modul bawaan Node.js: http, fs, path), routing server-side per-route, API endpoint (api.json), dan koneksi database generik (MySQL/PostgreSQL/MongoDB/SQLite) yang diatur lewat .env.

Tanpa dependency eksternal untuk core-nya (kecuali driver database yang kamu pilih sendiri).

Instalasi & Membuat Project Baru

npx fullwork init nama-project

CLI akan bertanya secara interaktif:

  • Nama project
  • Mode: Frontend atau Fullstack

Setelah selesai:

cd nama-project
npm run dev

Struktur Folder

project-root/
  config/         -> route.json, template.json, (api.json jika mode fullstack)
  style/          -> file CSS (di-inject ke <style> di <head>)
  page/           -> file HTML untuk slot "main" (konten per route)
  layout/         -> file HTML untuk slot header/navbar/sidebar/footer
  system/         -> kode internal framework (routing, render, server, dll) - jangan diedit
  logic/          -> SEMUA file JS milik kamu (client-side & handler API)
  index.html      -> shell HTML dasar
  .env            -> (mode fullstack) konfigurasi environment, termasuk database

Konsep Routing & Template

config/route.json

{
  "/": {
    "title": "Beranda",
    "template": "default",
    "page": "home.html",
    "css": "home.css",
    "js": "home.js",
    "mode": "client"
  }
}
  • title — judul halaman (document.title)
  • template — nama template dari template.json yang dipakai
  • page — file di folder page/ untuk slot main
  • css — file di folder style/
  • js — file di folder logic/, di-import otomatis saat main untuk route ini dirender
  • modekhusus mode Fullstack: "client" (default) atau "server". Menentukan apakah route ini dirender di browser (SPA) atau dirender penuh di server (SSR).

config/template.json

{
  "default": {
    "slots": ["header", "navbar", "footer"],
    "header": "header.html",
    "navbar": "navbar.html",
    "sidebar": "sidebar.html",
    "footer": "footer.html"
  }
}
  • slots — daftar slot tambahan yang dipakai template ini (pilih 1–4 dari: header, navbar, sidebar, footer). Slot yang tidak disebut di sini tidak dirender sama sekali.
  • header / navbar / sidebar / footer — nama file di folder layout/ untuk masing-masing slot.
  • Slot main wajib selalu ada di semua template, jadi tidak perlu (dan tidak boleh) ditulis di slots. Isinya selalu mengikuti properti page pada route.json, karena main memang berbeda-beda per route walau template-nya sama.

Struktur body yang dihasilkan

<body>
  <header>
    <nav>...</nav>   <!-- navbar selalu di dalam header -->
  </header>
  <main data-js="home.js">...</main>
  <aside>...</aside>  <!-- sidebar, kalau dipakai -->
  <footer>...</footer>
</body>

Saat pindah route:

  • Slot dengan file yang sama seperti sebelumnya → tidak dirender ulang.
  • Slot baru yang sebelumnya tidak dipakai → dirender.
  • Slot yang sebelumnya ada tapi sekarang tidak dipakai template baru → dihapus dari body.
  • CSS di <style> hanya diganti kalau nama file CSS-nya berbeda dari yang aktif.

Mekanisme JS (data-js + MutationObserver)

Setiap kali main dirender, system akan mengubah atribut data-js pada elemen <main> sesuai nilai js di route.json. Sebuah MutationObserver mengawasi perubahan atribut ini dan otomatis melakukan import() dinamis terhadap file yang bersangkutan dari folder logic/. Kamu tidak perlu memanggil import secara manual — cukup tulis file JS biasa di logic/.

Mode Fullstack

config/api.json

{
  "/api/users": {
    "method": "GET",
    "route": "/",
    "handler": "users-handler.getUsers",
    "db": true
  }
}
  • key — path endpoint API
  • methodGET / POST / PUT / DELETE
  • route — path di route.json yang menjadi "pemilik" konteks endpoint ini
  • handler — format namaFile.namaFungsi, merujuk ke logic/namaFile.js yang meng-export fungsi namaFungsi
  • dbtrue kalau handler ini butuh akses database (helper otomatis disiapkan lewat ctx.db)

Setiap endpoint di api.json otomatis mendapat header CORS (Access-Control-Allow-Origin: *) dan penanganan preflight OPTIONS bawaan, jadi API bisa dipanggil dari origin lain (misalnya aplikasi mobile hasil bundling Capacitor/Cordova, atau frontend yang di-deploy terpisah dari backend-nya) tanpa perlu konfigurasi tambahan.

Contoh handler di logic/users-handler.js:

module.exports.getUsers = async function (req, res, ctx) {
  res.writeHead(200, { "Content-Type": "application/json" });
  res.end(JSON.stringify({ users: [] }));
};

Database generik (.env)

DB_TYPE=sqlite   # mysql | postgres | mongodb | sqlite
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASS=
DB_NAME=fullwork_db
DB_URI=mongodb://localhost:27017/fullwork_db
DB_FILE=./data/database.sqlite

# Khusus koneksi postgres: set "true" kalau provider database mewajibkan SSL
# (contoh: Supabase, dan banyak provider database cloud lainnya).
DB_SSL=false

Framework tidak membundel driver database apa pun. Install sendiri sesuai DB_TYPE yang dipakai:

npm install mysql2          # DB_TYPE=mysql
npm install pg              # DB_TYPE=postgres
npm install mongodb         # DB_TYPE=mongodb
npm install better-sqlite3  # DB_TYPE=sqlite

Route server-side vs client-side

Set "mode": "server" pada entry di route.json supaya route tersebut dirender penuh di server (SSR) sebelum dikirim ke browser. Kalau tidak diset atau "mode": "client", route akan diserahkan ke sistem client-side (SPA) seperti mode Frontend biasa. Keduanya bisa dicampur dalam satu project yang sama.

Catatan

  • Semua kode di folder system/ adalah bagian internal framework — sebaiknya jangan diedit langsung kecuali kamu memang ingin memodifikasi cara kerja framework.
  • Semua kode yang kamu tulis (baik untuk client maupun handler API) selalu ditaruh di folder logic/.
  • Framework ini sengaja dibuat minim dependency supaya mudah dipahami dan dimodifikasi.

Lisensi

MIT