Skip to content

rudrachitambare/CtrlScript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

28 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CtrlScript

One codebase. Browser and Android. No setup. No BS.

import { App, Box, Text, Button, toast } from './csui.js'

const app = new App()
const card = new Box(app, { bg: '#111', br: 12, p: 20 })
new Text(card, { text: 'Hello world', fs: 24, color: '#fff' })
new Button(card, { text: 'Click' }).click(() => toast('πŸ”₯', { type: 'success' }))

No HTML. No CSS files. No npm. No config.

The entire library is a single file. Download csui.js, drop it in your project folder, import it, and you're done. No install step. No terminal. No build tools. Nothing else needed.

your-project/
β”œβ”€β”€ csui.js       ← this is all you need
β”œβ”€β”€ index.html
└── app.js

The problem

This is what building a UI in vanilla JS looks like:

const card = document.createElement('div')
card.style.backgroundColor = '#111'
card.style.borderRadius = '12px'
card.style.padding = '20px'

const title = document.createElement('span')
title.textContent = 'Hello world'
title.style.fontSize = '24px'
title.style.color = '#fff'
card.appendChild(title)

const btn = document.createElement('button')
btn.textContent = 'Click'
btn.addEventListener('click', () => alert('πŸ”₯'))
card.appendChild(btn)
document.body.appendChild(card)

This is what it looks like with CtrlScript:

const app = new App()
const card = new Box(app, { bg: '#111', br: 12, p: 20 })
new Text(card, { text: 'Hello world', fs: 24, color: '#fff' })
new Button(card, { text: 'Click' }).click(() => toast('πŸ”₯'))

Same result. A fraction of the code. And it only gets better from here.


What's inside

Everything ships in a single file β€” no installs, no imports from CDN unless you opt in.

UI

  • Components β€” Modal, Tabs, Drawer, Toast, Accordion, Card, Chip, Slider, ProgressBar, Toggle, Dropdown
  • Styling β€” full chaining API, shorthand props, glassmorphism, animations, tooltips, badges, context menus
  • Color β€” palette generator, bgRGB(), bgHSL()

Game

  • Delta-time loop, scene manager, camera, keyboard input, AABB collision
  • CSS-based particle bursts β€” no canvas needed
  • Matter.js physics β€” lazy-loaded, one line to enable

App

  • Router β€” URL-based, define() and go()
  • Storage β€” save() / load() via localStorage
  • Device APIs β€” geolocation, vibration, gyro, clipboard, notifications
  • Plugin system β€” extend any element or add global utilities

Chaining API

Every element supports a full chaining API:

new Box(app)
  .bg('#0f0f1a')
  .w(320).h(200)
  .br(16).p(20)
  .center()
  .glass({ pro: true, blur: 16 })
  .tooltip('Hello', { pos: 'top' })
// β†’ a centered frosted-glass card, centered in the viewport

Game in 15 lines

import { App, Box, loop, onKey, collides, particles, toast } from './csui.js'

const app = new App({ bg: '#000', w: '100vw', h: '100vh', pos: 'relative' })
const player = new Box(app, { w: 40, h: 40, bg: '#3b82f6', pos: 'absolute' })
const enemy  = new Box(app, { w: 40, h: 40, bg: '#ef4444', pos: 'absolute' }).x(300).y(200)

let px = 100, py = 300
onKey('arrowleft',  () => px -= 5)
onKey('arrowright', () => px += 5)
onKey('arrowup',    () => py -= 5)
onKey('arrowdown',  () => py += 5)

loop(dt => {
  player.x(px).y(py)
  if (collides(player, enemy)) {
    particles.emit({ x: px, y: py, color: '#3b82f6', count: 20 })
    toast('Hit!', { type: 'error' })
  }
})

Drop in and go

<script type="module">
  import { App, Box, Text } from './csui.js'

  const app = new App()
  new Text(app, { text: 'Running.', fs: 32, color: '#fff' })
</script>

No terminal. No node_modules. Works offline. Works on low-end devices.


csui-A β€” Android Runtime

🚧 Work in progress

csui-A is CtrlScript's Android runtime. It runs your JS natively on Android using QuickJS + JNI β€” no WebView, no Electron, no Capacitor.

The goal: write once, run on browser and Android natively. Same API, same syntax, same file.

// runs identically on web and Android
import { App, Box, Text, device } from './csui.js' // or csua.js on Android

const app = new App()
new Text(app, { text: 'Hello from anywhere', fs: 24 })

device.vibrate(200)        // β†’ navigator.vibrate() on web
                           // β†’ Android Vibrator API on Android

statusBar.color('#1a1a2e') // β†’ graceful no-op on web
                           // β†’ native status bar tint on Android

Platform-specific APIs automatically bridge to the right implementation. On web, Android-only calls gracefully no-op or fall back to a browser equivalent β€” no if (platform === 'android') checks, no separate codebases.

Stack: QuickJS (JS engine) β†’ JNI bridge β†’ Android Canvas / Views / native APIs


Built by a developer who wanted full control without the overhead.
If you feel the same way, this is for you.