Skip to main content

Transform Your Web App to Desktop App in 10 Minutes

· 5 min read

In desktop applications, Electron has long been strong and successful. GitHub Desktop, VSCode, Figma, Notion, Feishu, CapCut, and Dewu are all based on it. But recently, the rising star Tauri has also attracted attention. It solves one of Electron's major pain points - extremely large bundle sizes.

We know that Electron is built on Google's Chromium core. After packaging, no matter how small the application is, it starts at least at 70MB. Tauri uses the operating system's built-in Webview1, dynamically linking to the webview at runtime. This makes its packaging very fast and the packaged applications much smaller.

Tauri differs from Electron in one aspect: Electron uses JavaScript to write backend services, while Tauri uses Rust. Rust has gained tremendous momentum in recent years - it's safer and performs better. Many applications have started embracing Rust, and it will likely become a frontend essential soon.

This article uses Tauri as the framework for building desktop applications. With just a little time, you can transform a Web application into a desktop application.

1. Open a Web Application

We'll use FocusTide as our conversion target. It's an open-source timer web application on GitHub:

First, let's clone the repository locally:

$ git clone git@github.com:Hanziness/FocusTide.git

Then install and run it:

# Install dependencies
$ yarn install

# Start service at localhost:3000
$ yarn dev

2. Install Tauri Dependencies

Using Mac as an example, you need to install CLang and macOS development dependencies:

$ xcode-select --install

Install Tauri:

$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

This command will install Rustup, which downloads and installs Rust-related dependencies. When installation succeeds, the console will display:

$ Rust is installed now. Great!

Installing Tauri on other operating systems:

  1. Windows: https://tauri.app/v1/guides/getting-started/prerequisites/#windows
  2. Linux: https://tauri.app/v1/guides/getting-started/prerequisites/#linux

3. Integrate Tauri into the Project

In the web application, first install Tauri-related npm packages:

$ npm install --save-dev @tauri-apps/cli

Add script command to package.json:

"scripts": {
"tauri": "tauri"
}

Then run Tauri initialization command:

$ npm run tauri init

After executing this command, it will generate the following Tauri project structure in the current web project:

After execution, there will be some questions to answer:

  1. What is your app name? Application name. This will be the official name of the packaged application.

  2. What should the window title be? Default window title. This will be the window title when opening the application. If we don't need this window later, we can hide it using the hiddenTitle field in tauri.conf.json.

  3. Where are your web assets (HTML/CSS/JS) located relative to the < current dir > /src-tauri/tauri.conf.json file that will be created? Production file path. This is the path of the frontend project after building, relative to /src-tauri/tauri.conf.json. FocusTide's build output is in the project's dist folder, so we enter ../dist.

  4. What is the URL of your dev server? Development server URL. FocusTide's development server URL is http://localhost:3000.

  5. What is your frontend dev command? Frontend development command. FocusTide's development command is yarn dev.

  6. What is your frontend build command? Frontend build command. FocusTide's build command is yarn generate.

After execution, src-tauri is generated, and we can run the project:

$ npm run tauri dev

We can see our application running in a window:

4. Build and Release

If development is complete, we can package the application:

$ npm run tauri build

After executing the build command, the packaged application will be stored in src-tauri/target/release/bundle. As you can see, the package is very small:

During Tauri packaging, it builds according to the current system platform. For example, on Mac it can only package .dmg and .app files, while on Windows it packages .msi and .exe files.

5. Deployment

After downloading, if we want to make this application public, we need to deploy it. Here we recommend Laf. We can use its cloud storage file management to upload our application and get a download link:

6. Finally

The entire conversion process is actually very simple and fast. If you spent more than 10 minutes, we apologize. If you want to dive deeper into desktop backend services, check out the Tauri official website.

Finally, I've uploaded the converted FocusTide project to my personal GitHub and named it "Lai Todo". Currently only available for Mac. Welcome to download it 👏🏻

Footnotes

  1. Tauri vs. Electron: A comparison, how-to, and migration guide: https://blog.logrocket.com/tauri-electron-comparison-migration-guide/

bit, byte, KB, GB, MG, TB, PB

· One min read

1bit 是计算机中最小的数据单位,1bit 就对应一个高低电位。

在计算机上下文中,各单位的换算关系如下:

1bit×8=1byte1bit \times 8 = 1byte 1byte×1024=1KB(kilobyte)1byte \times 1024 = 1KB (kilobyte) 1KB×1024=1MB(megabyte)1KB \times 1024 = 1MB (megabyte) 1MB×1024=1GB(gigabyte)1MB \times 1024 = 1GB (gigabyte) 1GB×1024=1TB(terabyte)1GB \times 1024 = 1TB (terabyte) 1TB×1024=1PB(petabyte)1TB \times 1024 = 1PB (petabyte)
warning

在十进制或者国际单位制中,会用 1000 作为进率,而不是 1024。注意区分上下文。


在 UTF-8 编码中

  1. 一个 US-ASCII 字符只需要 1byte
  2. 带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文等字符需要 2byte
  3. 其他语言(包括中日韩文字、东南亚文字、中东文字等)使用 3byte
  4. 极少数语言用 4byte

Swapping Values Without Intermediate Variables

· One min read

Here are three methods to swap values without using intermediate variables.

1. Addition and Subtraction

Assume we have variables:

let a = 2, b = 5

Swap:

a = a + b // a = 7

b = a - b // b = 2

a = a - b // a = 5

Disadvantages:

  • Can only handle numeric values
  • May overflow when adding large numbers

2. Multiplication and Division

Since we have addition and subtraction, we can naturally think of multiplication and division:

a = a * b // a = 10

b = a / b // b = 2

a = a / b // a = 5

Disadvantages:

  • Precision loss
  • Divisor cannot be 0

3. XOR Method

XOR is a mathematical operation where different values yield 1, same values yield 0:

Result
000
011
101
110

To perform XOR operations in computers, we need to convert values to binary first. a in binary is 010, b in binary is 101:

a = a ^ b // 010 ^ 101 = 111

b = a ^ b // 111 ^ 101 = 010

a = a ^ b // 111 ^ 010 = 101

Disadvantages:

  • Cannot handle floating-point variables

Summary

All three methods are clever tricks, only for learning purposes. It's best not to use them in production environments.

Simple Distinction Between Concurrency and Parallelism

· 2 min read

When I first started learning about concurrency and parallelism, I always got a bit confused. Now I'm finally taking the time to properly clarify the relationship between the two.

First, the word for concurrency is "Concurrency". The root "con-" means "together", and the root "current-" means "current", so the overall meaning is "things happening together".

The word for parallelism is "Parallelism". The root "parallel-" means parallel or side by side, so the overall meaning is "things happening in parallel", which can also be said as "things happening simultaneously".

Here's a vivid example mentioned by a Zhihu answerer:

You're eating a meal when the phone rings. You wait until you finish eating before answering. This means you support neither concurrency nor parallelism.

You're eating a meal when the phone rings. You stop to answer the phone, then continue eating after the call. This means you support concurrency.

You're eating a meal when the phone rings. You answer the phone while continuing to eat. This means you support parallelism.

The key to concurrency is having the ability to handle multiple tasks, not necessarily simultaneously. The key to parallelism is having the ability to handle multiple tasks simultaneously. So I think the most crucial point is: whether it's simultaneous.

From this Zhihu answerer, we can actually understand that: parallelism is a special case of concurrency. Concurrency only requires the ability to handle multiple tasks, while parallelism requires the ability to handle multiple tasks simultaneously.

With this in mind, let's clarify the concurrency and parallelism of multi-core and single-core CPUs.

First, for single-core CPUs: A single-core CPU is very clear - it can only do one thing at a time, so it cannot have parallelism, but it may have concurrency (if this CPU supports the ability to handle multiple tasks).

Second, for multi-core CPUs: Multi-core CPUs are composed of multiple single-core CPUs, so handling multiple tasks at the same time becomes effortless, thus having parallelism (having parallelism means definitely having concurrency, as we've already said parallelism is a special case of concurrency).

简要介绍进制和 ASCII 码表

· 4 min read

1. What is a Number System

  • Number System A number system, officially called "positional notation system", is a counting method. The most commonly used is the decimal system.
    • Decimal System The decimal system follows the "carry over at ten" rule, so it has 10 digits to represent numbers—0,1,2,3,4,5,6,7,8,9

In daily life, besides the decimal system, there are many other common number systems that you might not have noticed. For example, clocks use a base-60 system for seconds. The second hand goes from 0 to 59, then after one more second, it carries over to become one minute.

Speaking of computers, computers could also use the decimal system to represent numbers. So why do they specifically use binary? The reason is simple: binary only has 0 and 1, making it very simple to represent.

Why is binary simple? Because computers are fundamentally hardware, and choosing between two pathways versus ten pathways is definitely easier with the former. The only trade-off is that binary needs to take more steps to reach the same destination.

2. About Binary

Let's first look at how decimal numbers are represented. Suppose we have a decimal number (3107)10(3107)_{10}

Note

  1. Here the number (3107)10(3107)_{10} is enclosed in parentheses with a subscript 10, indicating it's in base 10 This subscript is used to indicate the number system. For example, (3107)8(3107)_{8} - notice the subscript is 8, so it's no longer decimal but octal Also, why don't we usually write it this way? Because decimal is so common that it's assumed by default
  2. Besides this notation, there's also the suffix letter method you might encounter: For example, 3107H - adding the letter H after a number indicates it's a hexadecimal number

This (3107)10(3107)_{10} can be broken down as:

3×103+1×102+0×101+7×1003×10^3+1×10^2+0×10^1+7×10^0

Now let's look at a binary number (1101)2(1101)_2, which can also be represented as:

1×23+1×22+0×21+1×201×2^3+1×2^2+0×2^1+1×2^0

Can you now understand why they're called decimal and binary systems?

For number system conversion, binary to decimal is simple. You take:

1×23+1×22+0×21+1×201×2^3+1×2^2+0×2^1+1×2^0

Then calculate in decimal:

8+4+0+18+4+0+1

Which equals (13)10(13)_{10}, so we can write (1101)2(1101)_2=(13)10(13)_{10}

3. What is ASCII Code

  • ASCII (American Standard Code for Information Interchange) - the name is quite long, but let's focus on the word "code"

We know that representing numbers in computers is relatively simple, but how do we represent text? For example, letters like a, b, c, d, punctuation marks, Chinese characters, etc.

Our predecessors came up with an excellent solution: create a table that stores these text symbols

Text Symbol
a
b
c

Then assign numbers to these text symbols in order:

NumberText Symbol
0a
1b
2c

When you need to retrieve them, just use the numbers. Want 'a'? Input 1. Want 'b'? Input 2, and so on (now you might understand the meaning of "code")

So ASCII code table was an early symbol table. How early? 1967, when Americans invented it. Americans only use 26 letters, plus various other symbols, so 128 characters were sufficient to cover everything.

Why 128? As mentioned earlier, computers use binary representation. Starting from number 0, going up to 127, that's exactly 128 numbers.

The smallest number is 0, the largest is 127. If we can represent the largest number, we can represent all smaller numbers too. (1111111)2(1111111)_2 equals 127, which we can expand as:

1×26+1×25+1×24+1×23+1×22+1×21+1×201×2^6+1×2^5+1×2^4+1×2^3+1×2^2+1×2^1+1×2^0

Also, this (1111111)2(1111111)_2 has 7 bits total, so we can say it's a 7-bit ASCII code table.