Skip to Content
DocumentationExample Apps

Example Apps

These are all working apps that persist their state on Hyperclay - they change the DOM and the DOM saves itself automatically.

Every example below uses HyperclayJS — a single script tag that gives your HTML file the ability to save itself, toggle between admin and visitor modes, and persist DOM changes automatically.

Explore HyperclayJS

We include jQuery versions as a familiar, easy-to-understand first example, but encourage you to explore the often much simpler Hyperclay-native syntax.

Counter

With jQuery

<!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> </head> <body> <div style="padding: 20px; text-align: center;"> <h1>Counter: <span class="counter">0</span></h1> <button class="increment">+</button> <button class="decrement">-</button> </div> <script> $('.increment').on('click', function() { $('.counter').text((i, text) => +text + 1); }); $('.decrement').on('click', function() { $('.counter').text((i, text) => +text - 1); }); </script> </body> </html>

With HyperclayJS

<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> </head> <body> <div style="padding: 20px; text-align: center;"> <h1>Counter: <span class="counter">0</span></h1> <button onclick="this.nearest.counter.textContent++">+</button> <button onclick="this.nearest.counter.textContent--">-</button> </div> </body> </html>

Todo List

With jQuery

<!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> </head> <body> <h1>My Todos</h1> <ul class="todo-list"> <li class="task template" style="display:none"> <input type="checkbox" class="task-checkbox"> <span class="task-text">New task</span> <button class="delete-btn" style="display: none;">×</button> </li> </ul> <button class="add-task" style="display: none;">Add Task</button> <script> const isEditMode = document.documentElement.getAttribute('editmode') === 'true'; if (isEditMode) { $('.delete-btn, .add-task').show(); $('.task-text').attr('contenteditable', 'true'); Sortable.create($('.todo-list')[0], { animation: 150 }); hyperclay.beforeSave(() => { $('.delete-btn, .add-task').hide(); $('.task-text').attr('contenteditable', 'false'); }); } $('.add-task').on('click', function() { const $newTask = $('.task.template').clone(); $newTask.removeClass('template').show(); $newTask.find('.task-text').attr('contenteditable', isEditMode); if (isEditMode) { $newTask.find('.delete-btn').show(); } $('.todo-list').append($newTask); }); $(document).on('click', '.delete-btn', function() { $(this).closest('.task').remove(); }); $(document).on('change', '.task-checkbox', function() { if ($(this).prop('checked')) { $(this).attr('checked', 'checked'); } else { $(this).removeAttr('checked'); } }); </script> </body> </html>

With HyperclayJS

<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> </head> <body> <h1>My Todos</h1> <ul sortable> <li class="task" style="display:none" onclone="this.style.display='block'"> <input type="checkbox" persist> <span editmode:contenteditable>New task</span> <button option:editmode="true" onclick="this.nearest.task.remove()">×</button> </li> </ul> <button option:editmode="true" onclick="this.nearest.task.before(this.nearest.task.cloneNode(true))">Add Task</button> </body> </html>

Note Pad

With jQuery

<!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> <style> textarea { width: 100%; height: 400px; padding: 10px; font-family: monospace; } </style> </head> <body> <h1>My Notes</h1> <textarea class="notepad" placeholder="Start typing..."></textarea> <script> const isEditMode = document.documentElement.getAttribute('editmode') === 'true'; const $notepad = $('.notepad'); if (!isEditMode) { $notepad.attr('readonly', true); } else { $notepad.on('input', function() { this.setAttribute('value', this.value); }); hyperclay.beforeSave(() => { $notepad.each(function() { this.textContent = this.getAttribute('value') || this.value; this.removeAttribute('value'); }); $notepad.attr('readonly', true); }); } </script> </body> </html>

With HyperclayJS

<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> <style> textarea { box-sizing: border-box; width: 100%; height: 400px; padding: 10px; font-family: monospace; } </style> </head> <body> <h1>My Notes</h1> <textarea persist viewmode:readonly placeholder="Start typing..."></textarea> </body> </html>

Timer

With jQuery

<!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/easytimer.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> </head> <body> <div style="text-align: center; padding: 50px;"> <h1 class="display">00:00</h1> <button class="start-btn">Start</button> <button class="stop-btn">Stop</button> <button class="reset-btn">Reset</button> </div> <script> const timer = new easytimer.Timer(); timer.addEventListener('secondsUpdated', function (e) { $('.display').text(timer.getTimeValues().toString(['minutes', 'seconds'])); }); $('.start-btn').on('click', function() { timer.start(); }); $('.stop-btn').on('click', function() { timer.pause(); }); $('.reset-btn').on('click', function() { timer.stop(); $('.display').text('00:00'); }); </script> </body> </html>

With HyperclayJS

<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/hyperclayjs@latest/src/hyperclay.js?preset=smooth-sailing" type="module"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/easytimer.min.js"></script> </head> <body> <div style="text-align: center; padding: 50px;"> <h1 id="display">00:00</h1> <button onclick="timer.start()">Start</button> <button onclick="timer.pause()">Stop</button> <button onclick="timer.stop(); display.textContent = '00:00'">Reset</button> </div> <script> const timer = new easytimer.Timer(); timer.addEventListener('secondsUpdated', function (e) { display.textContent = timer.getTimeValues().toString(['minutes', 'seconds']); }); </script> </body> </html>
”These aren’t apps, they’re just HTML pages you can modify!!”

Yes :)

Advanced Example Apps

Ready-to-use applications that demonstrate Hyperclay’s full potential. Each can be cloned and customized for your needs.

Dev Log 

A software developer’s work log for tracking daily progress and debugging sessions.

  • Features: Sortable entries, project categorization, monospace aesthetic
  • Use case: Technical journaling, development notes, team updates
  • Key patterns: DOM-based data storage, sortable lists, inline editing, category toggling

Writer 

A beautiful WYSIWYG editor for creating formatted documents.

  • Features: Rich text editing, image imports, syntax highlighting
  • Use case: Blog posts, documentation, formatted notes
  • Key patterns: Script as JSON database

Kanban 

A Trello-style project management board with drag-and-drop functionality.

  • Features: Draggable cards and columns, inline editing
  • Use case: Project tracking, workflow management, task organization
  • Key patterns: Template cloning

Landing 

A professional landing page template that’s ready to customize.

  • Features: Responsive design, markdown content, fill-in-the-blanks
  • Use case: Product launches, marketing pages, startups
  • Key patterns: Edit-mode popovers, undo/redo support
Last updated on