Build your first plugin
A small local notes tool, from two source files to an installed plugin.
You need Hay, a Hay account, and a text editor. Building the optional bundle with the SDK also needs Node.js. The source-folder route does not require an npm project.
Create a source folder
Make a folder named little-notes. Add manifest.json:
{
"schemaVersion": "hay.app/1",
"id": "example.little-notes",
"name": "Little notes",
"version": "0.1.0",
"description": "A small place for one useful note.",
"author": "Your name",
"entrypoint": "index.html",
"icon": "FileText",
"color": "#20242c",
"capabilities": ["storage"],
"views": [{"id": "main", "title": "Notes", "description": "Your note"}],
"intents": []
}Use an ID you control before sharing a real release. The example prefix is for this tutorial.
Add the interface
Add index.html. Keep scripts and styles inline; Hay injects the SDK before your script.
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Little notes</title>
<style>
body { max-width: 44rem; margin: 3rem auto; padding: 0 1rem;
font: 16px/1.6 system-ui; color: #20242c; }
textarea { box-sizing: border-box; width: 100%; min-height: 12rem;
padding: 1rem; font: inherit; }
button { margin-top: 1rem; padding: .6rem 1rem; font: inherit; }
</style>
<h1>Little notes</h1>
<label for="note">What would you like to keep?</label>
<textarea id="note"></textarea>
<button id="save" type="button" disabled>Save note</button>
<p id="status" role="status">Opening your note…</p>
<script>
const note = document.querySelector('#note');
const save = document.querySelector('#save');
const status = document.querySelector('#status');
async function start() {
try {
await Hay.ready;
note.value = await Hay.storage.get('note') ?? '';
status.textContent = '';
save.disabled = false;
} catch (error) { status.textContent = error.message; }
}
save.addEventListener('click', async () => {
save.disabled = true;
try {
await Hay.storage.set('note', note.value);
status.textContent = 'Note saved.';
} catch (error) { status.textContent = error.message; }
finally { save.disabled = false; }
});
start();
</script>
</html>Install and grant access
In Hay, open Plugins, choose Import local plugin, and select the source folder. Review the installation request. Then enable Local plugin storage in its installed card and choose Open a new task.
Installation itself grants no capabilities. If storage is off, the example reports the host error instead of pretending to save.
Test the saved copy
Save a note, leave the task, return, and check that it is still there. Revoke storage permission and check the error state. Try keyboard navigation, an empty note, and a narrow window.
A regular browser does not provide window.Hay. Test host integration inside Hay. Local previews should use explicitly labelled fixtures rather than pretending to provide the host.
Share it
Open Plugins / Share & publish, choose Little notes, and select Export plugin file. Send the .hay-plugin.json file to someone who uses Hay. Their records and permissions are their own.
For a reproducible source build, use the packager from the Hay SDK source:
node /path/to/hay/packages/sdk/build-plugin.mjs ./little-notesThe result is little-notes/dist/example.little-notes-0.1.0.hay-plugin.json. Read package formats before adding capabilities or sample data.