Local. Encrypted. Yours.
Local.
Encrypted.
Yours.
Notes and tasks, encrypted and synced. Free, forever.
Notes and tasks, encrypted and synced.
Free, forever.





//
Why skelenote
//
Why skelenote
//
Why skelenote
Everything you need.
Free. Forever.
Notes. Tasks. Projects. Backlinks. Encryption. Sync. Export. All of it free, out of the box.


Your key. Not ours.
Everything is encrypted with a 24-word Skeleton Key that only you control. We can't read your notes. Neither can anyone else.
Free. No Catch.
$0/month. No premium tier, no feature gates, no "free trial." The app you download is the full app.


//
How it works
//
How it works
//
How it works
Objects. Tasks. Sync. History.

import { NextApiRequest, NextApiResponse } from 'next' import { supabase } from '@/lib/supabase' export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method === 'GET') { // AI suggestion: Add pagination and filtering const { data, error } = await supabase .from('products') .select('*') .order('created_at', { ascending: false }) if (error) return res.status(500).json({ error }) return res.status(200).json(data) } }
Notes, tasks, and projects. All connected.
Everything is an object with properties. @mention anything to create a connection. Backlinks appear automatically—your knowledge graph builds itself.

export function validateEmail(email: string): boolean { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ return regex.test(email) } export function validatePassword(password: string): boolean { // ⚠️ Error: 'lenght' is not a property of string if (password.lenght < 8) { // ← Ligne 8 avec erreur return false } return /[A-Z]/.test(password) && /[0-9]/.test(password) }
Tasks that live with your notes.
Create tasks inline or in dedicated views. Set due dates, priorities, and recurring schedules. Check them off from anywhere.

import Stripe from 'stripe' const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2023-10-16' }) // AI suggestion: Add webhook handler export async function createPaymentIntent(amount: number) { try { const paymentIntent = await stripe.paymentIntents.create({ amount: amount * 100, // Convert to cents currency: 'usd', automatic_payment_methods: { enabled: true } }) return { clientSecret: paymentIntent.client_secret } } catch (error) { // Ghost text: Handle Stripe errors properly throw new Error(`Payment failed: ${error.message}`) } }
Works offline. Syncs without conflict when ready.
Edit the same note on two devices—even offline. Changes merge automatically when you reconnect. No conflicts, no servers you don't control.

import { validateEmail, hashPassword } from '../utils/auth' describe('Authentication', () => { describe('validateEmail', () => { it('should accept valid email addresses', () => { expect(validateEmail('user@example.com')).toBe(true) expect(validateEmail('test+tag@domain.co.uk')).toBe(true) }) it('should reject invalid email addresses', () => { expect(validateEmail('invalid')).toBe(false) expect(validateEmail('@example.com')).toBe(false) }) }) // AI suggestion: Add test for password hashing describe('hashPassword', () => { // Ghost text suggestions... }) })
Never lose a thought.
Every change is saved. Browse your full edit history, compare versions, and restore anything. Time travel for your notes.

import { NextApiRequest, NextApiResponse } from 'next' import { supabase } from '@/lib/supabase' export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method === 'GET') { // AI suggestion: Add pagination and filtering const { data, error } = await supabase .from('products') .select('*') .order('created_at', { ascending: false }) if (error) return res.status(500).json({ error }) return res.status(200).json(data) } }
Notes, tasks, and projects. All connected.
Everything is an object with properties. @mention anything to create a connection. Backlinks appear automatically—your knowledge graph builds itself.

export function validateEmail(email: string): boolean { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ return regex.test(email) } export function validatePassword(password: string): boolean { // ⚠️ Error: 'lenght' is not a property of string if (password.lenght < 8) { // ← Ligne 8 avec erreur return false } return /[A-Z]/.test(password) && /[0-9]/.test(password) }
Tasks that live with your notes.
Create tasks inline or in dedicated views. Set due dates, priorities, and recurring schedules. Check them off from anywhere.

import Stripe from 'stripe' const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2023-10-16' }) // AI suggestion: Add webhook handler export async function createPaymentIntent(amount: number) { try { const paymentIntent = await stripe.paymentIntents.create({ amount: amount * 100, // Convert to cents currency: 'usd', automatic_payment_methods: { enabled: true } }) return { clientSecret: paymentIntent.client_secret } } catch (error) { // Ghost text: Handle Stripe errors properly throw new Error(`Payment failed: ${error.message}`) } }
Works offline. Syncs without conflict when ready.
Edit the same note on two devices—even offline. Changes merge automatically when you reconnect. No conflicts, no servers you don't control.

import { validateEmail, hashPassword } from '../utils/auth' describe('Authentication', () => { describe('validateEmail', () => { it('should accept valid email addresses', () => { expect(validateEmail('user@example.com')).toBe(true) expect(validateEmail('test+tag@domain.co.uk')).toBe(true) }) it('should reject invalid email addresses', () => { expect(validateEmail('invalid')).toBe(false) expect(validateEmail('@example.com')).toBe(false) }) }) // AI suggestion: Add test for password hashing describe('hashPassword', () => { // Ghost text suggestions... }) })
Never lose a thought.
Every change is saved. Browse your full edit history, compare versions, and restore anything. Time travel for your notes.

import { NextApiRequest, NextApiResponse } from 'next' import { supabase } from '@/lib/supabase' export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method === 'GET') { // AI suggestion: Add pagination and filtering const { data, error } = await supabase .from('products') .select('*') .order('created_at', { ascending: false }) if (error) return res.status(500).json({ error }) return res.status(200).json(data) } }
Notes, tasks, and projects. All connected.
Everything is an object with properties. @mention anything to create a connection. Backlinks appear automatically—your knowledge graph builds itself.

export function validateEmail(email: string): boolean { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ return regex.test(email) } export function validatePassword(password: string): boolean { // ⚠️ Error: 'lenght' is not a property of string if (password.lenght < 8) { // ← Ligne 8 avec erreur return false } return /[A-Z]/.test(password) && /[0-9]/.test(password) }
Tasks that live with your notes.
Create tasks inline or in dedicated views. Set due dates, priorities, and recurring schedules. Check them off from anywhere.

import Stripe from 'stripe' const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2023-10-16' }) // AI suggestion: Add webhook handler export async function createPaymentIntent(amount: number) { try { const paymentIntent = await stripe.paymentIntents.create({ amount: amount * 100, // Convert to cents currency: 'usd', automatic_payment_methods: { enabled: true } }) return { clientSecret: paymentIntent.client_secret } } catch (error) { // Ghost text: Handle Stripe errors properly throw new Error(`Payment failed: ${error.message}`) } }
Works offline. Syncs without conflict when ready.
Edit the same note on two devices—even offline. Changes merge automatically when you reconnect. No conflicts, no servers you don't control.

import { validateEmail, hashPassword } from '../utils/auth' describe('Authentication', () => { describe('validateEmail', () => { it('should accept valid email addresses', () => { expect(validateEmail('user@example.com')).toBe(true) expect(validateEmail('test+tag@domain.co.uk')).toBe(true) }) it('should reject invalid email addresses', () => { expect(validateEmail('invalid')).toBe(false) expect(validateEmail('@example.com')).toBe(false) }) }) // AI suggestion: Add test for password hashing describe('hashPassword', () => { // Ghost text suggestions... }) })
Never lose a thought.
Every change is saved. Browse your full edit history, compare versions, and restore anything. Time travel for your notes.

import { NextApiRequest, NextApiResponse } from 'next' import { supabase } from '@/lib/supabase' export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method === 'GET') { // AI suggestion: Add pagination and filtering const { data, error } = await supabase .from('products') .select('*') .order('created_at', { ascending: false }) if (error) return res.status(500).json({ error }) return res.status(200).json(data) } }
Notes, tasks, and projects. All connected.
Everything is an object with properties. @mention anything to create a connection. Backlinks appear automatically—your knowledge graph builds itself.

export function validateEmail(email: string): boolean { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ return regex.test(email) } export function validatePassword(password: string): boolean { // ⚠️ Error: 'lenght' is not a property of string if (password.lenght < 8) { // ← Ligne 8 avec erreur return false } return /[A-Z]/.test(password) && /[0-9]/.test(password) }
Tasks that live with your notes.
Create tasks inline or in dedicated views. Set due dates, priorities, and recurring schedules. Check them off from anywhere.

import Stripe from 'stripe' const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2023-10-16' }) // AI suggestion: Add webhook handler export async function createPaymentIntent(amount: number) { try { const paymentIntent = await stripe.paymentIntents.create({ amount: amount * 100, // Convert to cents currency: 'usd', automatic_payment_methods: { enabled: true } }) return { clientSecret: paymentIntent.client_secret } } catch (error) { // Ghost text: Handle Stripe errors properly throw new Error(`Payment failed: ${error.message}`) } }
Works offline. Syncs without conflict when ready.
Edit the same note on two devices—even offline. Changes merge automatically when you reconnect. No conflicts, no servers you don't control.

import { validateEmail, hashPassword } from '../utils/auth' describe('Authentication', () => { describe('validateEmail', () => { it('should accept valid email addresses', () => { expect(validateEmail('user@example.com')).toBe(true) expect(validateEmail('test+tag@domain.co.uk')).toBe(true) }) it('should reject invalid email addresses', () => { expect(validateEmail('invalid')).toBe(false) expect(validateEmail('@example.com')).toBe(false) }) }) // AI suggestion: Add test for password hashing describe('hashPassword', () => { // Ghost text suggestions... }) })
Never lose a thought.
Every change is saved. Browse your full edit history, compare versions, and restore anything. Time travel for your notes.
A connected workspace
Tasks built-in
Offline + sync
Time machine

import { NextApiRequest, NextApiResponse } from 'next' import { supabase } from '@/lib/supabase' export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method === 'GET') { // AI suggestion: Add pagination and filtering const { data, error } = await supabase .from('products') .select('*') .order('created_at', { ascending: false }) if (error) return res.status(500).json({ error }) return res.status(200).json(data) } }
Notes, tasks, and projects. All connected.
Everything is an object with properties. A note can have tags, due dates, or link to a project. @mention anything to create connections. Your knowledge graph builds itself.
A connected workspace
Tasks built-in
Offline + sync
Time machine

import { NextApiRequest, NextApiResponse } from 'next' import { supabase } from '@/lib/supabase' export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method === 'GET') { // AI suggestion: Add pagination and filtering const { data, error } = await supabase .from('products') .select('*') .order('created_at', { ascending: false }) if (error) return res.status(500).json({ error }) return res.status(200).json(data) } }
Notes, tasks, and projects. All connected.
Everything is an object with properties. A note can have tags, due dates, or link to a project. @mention anything to create connections. Your knowledge graph builds itself.
Daily Notes
A new page for each day, created automatically. Link anything to today. Build a journal without thinking about it.
Daily Notes
A new page for each day, created automatically. Link anything to today. Build a journal without thinking about it.
Daily Notes
A new page for each day, created automatically. Link anything to today. Build a journal without thinking about it.
Command Palette
Cmd+K opens everything. Create, search, navigate, run actions. Power users know the drill.
Command Palette
Cmd+K opens everything. Create, search, navigate, run actions. Power users know the drill.
Command Palette
Cmd+K opens everything. Create, search, navigate, run actions. Power users know the drill.
Templates
Start with structure, not a blank page. Meeting notes, project briefs, weekly reviews—ready when you are.
Templates
Start with structure, not a blank page. Meeting notes, project briefs, weekly reviews—ready when you are.
Templates
Start with structure, not a blank page. Meeting notes, project briefs, weekly reviews—ready when you are.
PARA Method
Built-in support for Projects, Areas, Resources, and Archive. Organize by actionability, not folders.
PARA Method
Built-in support for Projects, Areas, Resources, and Archive. Organize by actionability, not folders.
PARA Method
Built-in support for Projects, Areas, Resources, and Archive. Organize by actionability, not folders.
Semantic Search
Find notes by meaning, not keywords. Search "Q3 budget meeting" even if you wrote "finance sync."
Semantic Search
Find notes by meaning, not keywords. Search "Q3 budget meeting" even if you wrote "finance sync."
Semantic Search
Find notes by meaning, not keywords. Search "Q3 budget meeting" even if you wrote "finance sync."
Keyboard First
Navigate, edit, and organize without touching your mouse. Every action has a shortcut.
Keyboard First
Navigate, edit, and organize without touching your mouse. Every action has a shortcut.
Keyboard First
Navigate, edit, and organize without touching your mouse. Every action has a shortcut.
//
Get skelenote
//
Get skelenote
//
Get skelenote
Available everywhere you work.
Available everywhere
you work.

Desktop
Full-featured native app. Works offline. Syncs when you want it to.

Desktop
Full-featured native app. Works offline. Syncs when you want it to.

Desktop
Full-featured native app. Works offline. Syncs when you want it to.

Mobile
Capture on the go. QR-pair with your desktop. Same encryption, pocket-sized.

Mobile
Capture on the go. QR-pair with your desktop. Same encryption, pocket-sized.

Mobile
Capture on the go. QR-pair with your desktop. Same encryption, pocket-sized.

Early Access
Be first to try new features. Help shape the product.
//
FAQs
//
FAQs
//
FAQs
The answers you expect
before trusting us.
The answers you expect before trusting us.
The answers you expect before trusting us.
Can you read my notes?
How do I know the encryption is real?
How is skelenote free?
What happens if skelenote shuts down?
Who makes skelenote?
What happens if I lose my Skeleton Key?
Where is my data stored?
What platforms are supported?
How do I sync between devices?
Can I export my data?
Is skelenote open source?
How does skelenote compare to other notes apps?
Can you read my notes?
How do I know the encryption is real?
How is skelenote free?
What happens if skelenote shuts down?
Who makes skelenote?
What happens if I lose my Skeleton Key?
Where is my data stored?
What platforms are supported?
How do I sync between devices?
Can I export my data?
Is skelenote open source?
How does skelenote compare to other notes apps?
Can you read my notes?
How do I know the encryption is real?
How is skelenote free?
What happens if skelenote shuts down?
Who makes skelenote?
What happens if I lose my Skeleton Key?
Where is my data stored?
What platforms are supported?
How do I sync between devices?
Can I export my data?
Is skelenote open source?
How does skelenote compare to other notes apps?
Need help? Join the community.
Need help?
Join the community.
Get answers, share ideas, and connect with other users.
Notes and tasks, encrypted and synced.
Free, forever.
