Developing a desktop note-taking app with Tauri (React + Rust)
Hello friends!
In this tutorial, we will develop a desktop application using Tauri. Tauri
is a framework for creating desktop applications, similar to Electronbut allowing to use Rust instead of Node.jsfor example, to interact with the file system.
As a framework for developing a user interface, I will use React and typescriptand to work with dependencies for JavaScript
— Yarn.
Served as a source of inspiration for me this wonderful article.
note: I will develop an application under Windows x64
other operating systems (and architectures) will have slightly different implementation details.
The application will be a kind of one-line terminal for writing notes to a file tasks.txt
located in the home directory (for Windows
– this is C:\Users\[User]
). The app will launch with a keyboard shortcut Ctrl + Shift + Q
and end when pressed Esc
.
Here’s what it will look like:
If you are interested, please under cat.
Preparing and setting up a project
note: must be installed on your machine Node.js and Rust
. About installation Rust
you can read here and here.
If you use as a code editor VSCodeI recommend installing this set of extensions to work with Rust
.
Windows
- When installing Build Tools for Visual Studio 2022 select payload
Разработка классических приложений на C++
.
- After installation
Rust
execute the commandrustup default stable-msvc
in terminal to switch to toolboxMSVC
.
Create a new project Tauri
:
yarn create tauri-app
- Enter the name of the application, for example,
Tauri Focus
; - choose a tool for creating a frontend template create-vite;
- add a package @tauri-apps/api;
- choose a template react-ts.
note: in Windows
command prompt must be run as administrator.
Go to the created directory tauri-focus
and bring it to the following form:
Ignore the files for now postcss.config.js
and tailwind.config.js
you will have them soon.
Execute the command yarn tauri dev
to run the application in development mode. note: at first start Rust
you will need to compile the application files, so you will have to wait a bit (on subsequent launches, the cache will be used).
This completes the preparation and configuration of the project. Let’s move on to the development of the user interface.
User interface
To style the application, we will use TailwindCSS. Install the necessary packages, being in the root directory of the project:
yarn add -D tailwindcss postcss autoprefixer
Initialize Tailwind
:
yarn tailwindcss init -p
Add to tailwind.config.js
next line:
module.exports = {
// если хотите, можете оставить здесь только `tsx`
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
// ...
}
Import styles to src/index.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
Editing the file src/App.tsx
:
import React, { useState } from 'react'
function App() {
const [text, setText] = useState('')
const addTask = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
console.log(text)
}
}
return (
<input
type="text"
className="w-[600px] h-[60px] px-4 bg-gray-800 text-2xl text-green-600 rounded-sm"
value={text}
onChange={(e) => setText(e.target.value)}
onKeyDown={addTask}
/>
)
}
export default App
We have a (dark) field of size 600x60px
to enter (green) note text. When you press Enter
the value of this field is output to the console.
Next, we need a function to write a note to a file.
Interaction with the file system
Define a team Tauri
/function to write a note in a file src-tauri/src/main.rs
:
// импорт зависимостей
use std::fs::OpenOptions;
use std::io::Write;
#[tauri::command]
fn add_task(text: String) {
let mut file = OpenOptions::new()
.create(true)
.append(true)
.open("../tasks.txt")
.expect("Ошибка при открытии файла");
writeln!(file, "{}", text).expect("Ошибка при записи файла");
}
Add this function to the list of commands:
fn main() {
let context = tauri::generate_context!();
tauri::Builder::default()
// !
.invoke_handler(tauri::generate_handler![add_task])
.menu(tauri::Menu::os_default(&context.package_info().name))
.run(context)
.expect("Ошибка при запуске приложения");
}
Editing the handler addTask
in src/App.tsx
(вызов Rust
from the frontend):
import { invoke, process } from '@tauri-apps/api'
// ...
const addTask = async (e: React.KeyboardEvent) => {
switch (e.key) {
// при нажатии `Enter` вызываем `add_task` с текстом заметки
case 'Enter':
try {
await invoke('add_task', { text })
setText('')
} catch (e) {
console.error(e)
}
break
// при нажатии `Esc` завершаем процесс
case 'Escape':
return process.exit()
default:
return
}
}
// ...
Application health check and finishing touches
Before running the application, you need to edit the file a little tauri.conf.json
:
"tauri": {
"bundle": {
"identifier": "app.tauri.focus",
},
"windows": [
{
"fullscreen": false,
"resizable": false,
"center": true,
"width": 600,
"height": 60,
"title": "Tauri Focus App",
"decorations": false
}
]
}
decorations: false
means hiding the header, the rest, I think, is clear.
- Execute the command
yarn tauri dev
(notethat the frontend can be debugged separately athttp://localhost:3000
); - enter some test values, for example,
test
,test2
,test3
; - we see that a file has appeared in the root of the project
tasks.txt
with our notes.
If you are confused by the error on this line:
let context = tauri::generate_context!();
Just create a frontend build with the command yarn build
.
Excellent. The app is working as expected. However, the project root is not a very good place to store the file. tasks.txt
. Also, we haven’t generated the setup file yet.
For universal access to the home directory, you need the package home (“crate” in terminology Rust
). Add to file src-tauri/src/Cargo.toml
this line:
[dependencies]
# ...
home = "0.5.3"
Importing the package into main.rs
and define a variable for the path to the home directory:
// ...
use home::home_dir;
fn add_task(text: String) {
// !
let mut path = home_dir()
.expect("Ошибка доступа к домашней директории");
// добавляем в путь название файла для заметок
path.push("tasks.txt");
let mut file = OpenOptions::new()
.create(true)
.append(true)
// !
.open(path)
.expect("Ошибка при открытии файла");
writeln!(file, "{text}").expect("Ошибка при записи файла");
}
Execute the command yarn tauri build
:
This will generate the setup file src-tauri/target/release/bundle/msi/tauri-focus_0.1.0_x64_en-US.msi
.
Also in the directory src-tauri/target/release
executable is generated tauri-focus.exe
.
- Create a shortcut for this file on the desktop;
- open the properties of the shortcut;
- in the “Shortcut” field, enter a keyboard shortcut to launch the application, for example,
Ctrl + Shift + Q
; - apply the changes.
Click Ctrl + Shift + Q
and add a couple of notes:
pressing Esc
terminates the application.
Perhaps this is all I wanted to share with you in this article. I hope you found something interesting for yourself and did not waste your time.
Thank you for your attention and happy coding!