In this engirring blog, we introduce the learning topics we work on daily.

What is Local-First?
Recently, the concept of Local-First has been gaining attention. Many applications are designed with an online-first approach, where data is stored in the cloud. This allows users to access their data from any device and easily share it with others. However, applications that rely on online connectivity have several disadvantages, such as:
- Data is inaccessible without an internet connection.
- The application becomes unusable if the server goes down.
- Communication with the server can introduce delays, reducing responsiveness.
- Storing personal data in the cloud poses security risks from external access.
The Local-First approach addresses these issues. In Local-First applications, data is primarily stored on the user’s device and synchronized only when needed. This approach offers several benefits:
- Data remains accessible even without an internet connection.
- The application functions independently, unaffected by service outages.
- Immediate data read/write operations without relying on a server.
- Personal data is managed locally, reducing dependency on the cloud.
Examples of Local-First Applications
Several applications utilize the Local-First approach, including:
- Evernote: Allows users to create and view notes even while offline. Synchronization with the cloud ensures data availability across devices.
- Notion: An all-in-one productivity tool featuring document management, task tracking, and database functionality. Users can edit content offline, and changes are synced to the cloud to maintain data consistency.
Let’s Build an Application! (TypeScript Edition)
To experience the Local-First approach, let’s build a simple To-Do App that runs entirely within a browser! This application will store data locally, ensuring that tasks remain saved even after a page reload.
Below, we introduce the key implementation details.
ToDo の追加(データをローカルに保存) async function addTodo(text: string) { const todo = { _id: new Date().toISOString(), // 一意のID text, completed: false }; // データをローカルに保存 await db.put(todo); } ToDo の表示(保存されたデータを取得) async function renderTodos() { const result = await db.allDocs({ include_docs: true }); result.rows.forEach(row => { // タスクを取得して表示 console.log(row.doc.text); }); } ToDo の削除 async function deleteTodo(id: string) { const doc = await db.get(id); // タスクを削除 await db.remove(doc); }
Running the To-Do App

- Open the application in a web browser.
- Enter a task and click the Add button—the task will be added to the list below.
- Close the browser. (Normally, this would cause the entered tasks to be lost.)
- Reopen the application in the browser. (The previously entered tasks remain displayed.)
- Click on a task to delete it.
Thoughts on Running the App
One of the standout features of this To-Do App is its ability to function independently of the internet, managing data entirely within the browser. By storing data locally, users can continue using the application even while offline.
Key Takeaways:
- Data persists even after a page reload!
- The app works without a server!
- Fast performance with instant data retrieval!
Applications that don’t rely on servers or the cloud might seem somewhat uncommon, but the Local-First approach proves to be highly valuable for offline functionality and data privacy. While this project was a simple implementation, it could be extended with cloud synchronization or mobile support for a more versatile experience.
Exploring the possibilities of Local-First applications has been insightful, and I look forward to leveraging this concept further.
See you in the next blog post!