Welcome to the final chapter of our secureStorage tutorial!
In the previous chapter, Keychain State Caching, we sped up our application by remembering the password after we fetched it once. This made the application very fast after the first request.
However, we still have one problem: The First Read.
When your application first launches, the cache is empty. It must go to the "basement" (the macOS Keychain) to fetch the credentials. As we learned, this takes about 65 milliseconds. That might sound fast, but in the world of application startup, every millisecond counts.
Imagine you are going to a coffee shop before work.
Method A: The Normal Way (Synchronous)
Total wait after arrival: 5 minutes.
Method B: The Prefetch Way (Parallel)
Total wait after arrival: 0 minutes.
Parallel Startup Prefetching is Method B. Instead of waiting for the application to fully load before asking for the password, we send the "Order" (the Keychain request) the very instant the user clicks the app icon. By the time the app finishes loading its heavy files (walking to the shop), the password (coffee) is ready.
Node.js applications have to "import" many files at startup. This takes time (CPU work). While the CPU is busy reading files, the "Network" or "System Command" lane is completely empty.
We want to utilize that empty lane.
Goal: Start the security command immediately, so it runs in the background while the main application logic (main.tsx) is being imported.
Let's visualize the timeline comparison.
We effectively save roughly 65ms of startup time by overlapping the work.
To make this work, we have to be very careful about dependencies.
If our "Pre-order" script imports heavy libraries (like the ones we use for the main app), it defeats the purpose! It would take too long to start the script. We must use lightweight, native tools.
We use the native Node.js child_process module directly. We do not use the execa library we used in Chapter 2, because loading execa takes time.
// File: keychainPrefetch.ts
import { execFile } from 'child_process'
import { getUsername } from './macOsKeychainHelpers.js'
// We define a promise so we can track the background task
let prefetchPromise: Promise<void> | null = null
We create a function that fires the command but does not wait for it to finish immediately. It just starts the process and stores the "receipt" (the Promise).
export function startKeychainPrefetch(): void {
// Only run on Mac
if (process.platform !== 'darwin') return
// Fire the command!
// We don't use 'await' here because we want the app
// to keep loading while this runs.
const mySpawn = spawnSecurity('Claude Code-credentials')
// Save the promise so we can check it later
prefetchPromise = Promise.all([mySpawn]).then((result) => {
// Save result to cache (Concept 3)
primeKeychainCacheFromPrefetch(result[0].stdout)
})
}
This helper wraps the native execFile command. It's the rawest way to talk to the OS.
function spawnSecurity(serviceName: string): Promise<any> {
return new Promise(resolve => {
execFile(
'security',
['find-generic-password', '-a', getUsername(), '-w', '-s', serviceName],
{ encoding: 'utf-8', timeout: 10000 },
(err, stdout) => {
// Resolve with the data (or null if failed)
resolve({ stdout: stdout?.trim() || null })
}
)
})
}
Remember keychainCacheState from Chapter 4?
When our background process finishes, we inject the data directly into that memory cache.
// File: macOsKeychainHelpers.ts
export function primeKeychainCacheFromPrefetch(stdout: string | null): void {
// If the main app already fetched data, don't overwrite it.
if (keychainCacheState.cache.cachedAt !== 0) return
// Parse the raw string from the CLI into JSON
const data = JSON.parse(stdout)
// Put it in the "sticky note" memory spot
keychainCacheState.cache = {
data,
cachedAt: Date.now()
}
}
Finally, in our main application file (main.tsx), we need a checkpoint. Just before the app tries to use the credentials, it ensures the prefetch has finished.
Usually, the prefetch finishes way before this line of code is reached. But if the computer is slow, we await here to be safe.
// File: main.tsx
// 1. Start the prefetch at the very top of the file
startKeychainPrefetch()
// ... lots of heavy imports happen here ...
async function main() {
// 2. Before we start, make sure the background task is done
await ensureKeychainPrefetchCompleted()
// 3. Now the cache is primed! This read is instant.
const storage = getSecureStorage()
const data = storage.read()
}
In this final chapter, we implemented Parallel Startup Prefetching.
child_process.execFile (a lightweight tool) to fire the keychain request immediately at startup.Congratulations! You have built a production-grade secure storage system. Let's review what you've accomplished:
security CLI) using Hex encoding and pipes.You now have a storage engine that is Secure, Resilient, and Incredibly Fast.
Generated by Code IQ