
Security News
Lovable’s OJ Rewrites Vite’s Dev Server in Rust as AI Lowers the Cost of Forking Open Source
Lovable’s OJ rewrites Vite’s dev server in Rust, reducing memory use and preview times as AI lowers the cost of open source reimplementation.
react-native-nitro-logger
Advanced tools
Structured, privacy-tiered logging for React Native — TS core with a native Nitro file/os_log sink
Structured, privacy-tiered logging for React Native. A TypeScript core with native file and system-console sinks built on Nitro Modules.
npm install react-native-nitro-logger react-native-nitro-modules
react-native-nitro-modules is a required peer — this library is built on
Nitro Modules.
import {
Log,
ConsoleDestination,
FileDestination,
createFileSink,
} from 'react-native-nitro-logger';
Log.addDestination(new ConsoleDestination());
Log.addDestination(new FileDestination(createFileSink()));
Log.info('app started');
Log.warning('retrying upload', { attempt: 2, statusCode: 503 });
A scoped logger tags every line with a correlation ID, so one request's lines can be picked out of a busy file. Omit the correlation argument and one is generated for you — which is also what the lint rules want, since a correlation ID must never be derived from an identifier you already have:
const scope = Log.scoped(undefined, 'checkout', { orderKind: 'subscription' });
scope.info('payment authorised');
scope.error('capture failed', { statusCode: 502 });
verbose · debug · info · warning · error · todo
Log.minimumLevel('info'); // globally
Log.subsystem('networking', 'debug'); // and per subsystem
The default profile renders metadata values and is fine for open-source and general application use. Apps handling regulated data should switch to the strict one in their entry point, before anything logs:
import { Log, pub, priv } from 'react-native-nitro-logger';
Log.privacyDefault('private');
Log.metadataKeyCatalog(['requestId', 'statusCode', 'durationMs']);
Log.info('request finished', {
requestId: pub(id), // rendered
statusCode: 200, // redacted — unwrapped, and the default is private
});
In a release build (__DEV__ false):
'public' (default) | 'private' | |
|---|---|---|
| bare value | rendered | <private> |
pub(v) | rendered | rendered |
priv(v) | <private> | <private> |
A debug build renders private payloads in the clear, to every destination including the file — so the fail-closed behaviour above is a property of the builds that ship, not of every build. A build where reveal is possible is a build for synthetic data only.
privacyDefault is first-set-wins and tighten-only, so a dependency cannot
loosen your setting.
Message text, metadata keys, subsystems and correlation IDs are public by contract — they are never redacted at runtime. The bundled ESLint plugin constrains them at build time instead, but only once you enable it: installing this package ships the rules, it does not apply them.
// eslint.config.mjs
import nitroLogger from 'react-native-nitro-logger/eslint-plugin';
export default [nitroLogger.configs.strict];
Read docs/PRIVACY.md before using this in an app that handles regulated data. It covers what the contract does and does not promise, the approved-key catalog, and the compliance boundary — in short, a build where reveal is possible is a build for synthetic data only.
const file = new FileDestination(createFileSink(), {
rotation: {
maxFileSizeBytes: 10 * 1024 * 1024,
maxArchivedFilesCount: 5,
compressArchives: true,
maxTotalLogBytes: 50 * 1024 * 1024,
},
});
Log.addDestination(file);
Logs live in app-private storage — noBackupFilesDir on Android, Library/Logs
on iOS. Owner-only modes are applied to every artifact; where the platform
refuses, the sink reports a protection degradation and keeps logging rather
than failing shut.
file.getLogFilePaths(); // for a consent-gated support upload
const outcome = file.purge(5000); // the compliance purge
if (!outcome.durable) {
// Something survived, or the deadline blew. The destination stays fenced
// until an explicit retry, so nothing is written into a pending deletion.
}
purge is synchronous and deadline-bounded. It reports durable (every
pre-purge artifact is gone) separately from rebound (the destination is
writable again), because a complete deletion can still be followed by a failed
reopen, and a caller that resumes on durable alone would write into a
destination with nowhere to put anything. A purge that rebinds opens a fresh,
empty active file — durable is a statement about the data that was there, not
a promise that the directory is left empty.
It clears the file sink's artifacts and nothing else. Anything already
handed to os_log or logcat is outside this library's reach.
import { installErrorHandler, flushOnBackground } from 'react-native-nitro-logger';
const uninstallHandler = installErrorHandler();
const uninstallFlush = flushOnBackground();
The error handler logs uncaught errors with the message dropped outside dev, the class name reduced to a built-in or a fixed token, and stack frames reduced to a position in a file whose name was already known. It flushes on fatal errors, then chains to whatever handler was installed before it. Both functions return idempotent uninstall handles.
JsonLinesFormatter is the default for files — one JSON object per line, with
a framing guarantee the native crash-tail recovery depends on. It is asserted
byte-identical to SwiftLogger's JSONLogFormatter over a
generated corpus.
{"timestamp":"2026-07-28T10:15:00.123Z","level":"INFO","message":"app started"}
DefaultFormatter is the human-readable one used by the console destination.
Custom formatters implement LogFormatter; declare framing: 'line' to opt
into crash-tail trimming.
| Supported | Verified | |
|---|---|---|
| iOS | React Native ≥ 0.78 | CI builds, launches and exercises a pristine 0.78 consumer app |
| Android | React Native at the example's version; ≥ 0.78 experimental. minSdk 24 | CI runs the writer's unit suite and builds the example; no minimum-version consumer job exists yet |
New Architecture only. The compatibility claims are split per platform on purpose — see docs/PARITY.md for what backs each one, and for where the two native writers genuinely differ.
MIT
FAQs
Structured, privacy-tiered logging for React Native — TS core with a native Nitro file/os_log sink
The npm package react-native-nitro-logger receives a total of 2 weekly downloads. As such, react-native-nitro-logger popularity was classified as not popular.
We found that react-native-nitro-logger demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Lovable’s OJ rewrites Vite’s dev server in Rust, reducing memory use and preview times as AI lowers the cost of open source reimplementation.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.