Granite Documentation
repository·main·Indexed 19 days ago
https://github.com/toss/graniteA Gradle plugin that enables React Native features, including TurboModules, Fabric, and JS bundling, within Android Library modules (AAR). The ecosystem includes @granite-js/forge for application management and @granite-js/pulumi-aws for automating React Native CDN infrastructure on AWS using the ReactNativeBundleCDN component.
What's inside Granite
- @granite-js/native serves as a native module hub package for the Granite ecosystem. It is designed to centralize and manage native modules used within Granite applications.
Overview of @granite-js/react-native
mainThe@granite-js/react-nativepackage is part of the Granite Framework, designed for React Native development.Overview of @granite-js/lottie
main@granite-js/lottieis a Lottie component package designed for use within the Granite ecosystem. It provides components to render Lottie animations.Overview of @granite-js/plugin-router
main@granite-js/plugin-router is a Route Generator designed specifically for Granite projects. It automates the creation and management of routes within a Granite application structure.Overview of @granite-js/mpack
main@granite-js/mpack is a specialized bundler designed specifically for Granite applications.Use @granite-js/plugin-rozenite for Rozenite integration
main@granite-js/plugin-rozenite is an integration plugin designed to connect Rozenite with Granite applications.Use @granite-js/forge to manage Granite applications
main@granite-js/forgeis a command-line interface (CLI) tool designed for managing Granite applications. It provides the necessary tooling to handle application lifecycles and management tasks within the Granite ecosystem.How layout application scope and nesting works
mainThe scope of a
_layout.tsxfile is determined by its location in the file system:pages/_layout.tsx: Applies to all pages in the application (Global Layout).pages/about/_layout.tsx: Applies to all pages within theaboutdirectory (e.g.,<scheme>://{serviceName}/about/indexand<scheme>://{serviceName}/about/team).
Nesting: Layouts are applied sequentially from the top-level directory down to the specific page. For a file at
pages/about/team.tsx, the application order is:pages/_layout.tsx(Top-level)pages/about/_layout.tsx(Section-level)pages/about/team.tsx(The page itself)
Understand the Pulumi Project Layout
mainThe template follows a standard Pulumi TypeScript structure:
Pulumi.yaml: Contains Pulumi project and template metadata.index.ts: The main Pulumi program where resources (like the S3 bucket) are defined.package.json: Manages Node.js dependencies.tsconfig.json: Defines TypeScript compiler options.
Use automatically generated type definitions for safe routing
mainThe router plugin automatically generates type definitions in a file (typically
src/router.gen.ts) that augments the@granite-js/react-nativemodule. It populates theRegisterScreenInputandRegisterScreeninterfaces with your specific paths and their corresponding input/output types. This ensures that if you attempt to navigate to a non-existent path or provide incorrect parameters, TypeScript will throw an error during development.// src/router.gen.ts /* eslint-disable */ // This file is auto-generated by @granite-js/react-native. DO NOT EDIT. import { Route as _PageARoute } from '../pages/page-a'; import { Route as _PageBRoute } from '../pages/page-b'; import { Route as _PageCRoute } from '../pages/page-c'; declare module '@granite-js/react-native' { interface RegisterScreenInput { '/page-a': (typeof _PageARoute)['_inputType']; '/page-b': (typeof _PageBRoute)['_inputType']; '/page-c': (typeof _PageCRoute)['_inputType']; } interface RegisterScreen { '/page-a': (typeof _PageARoute)['_outputType']; '/page-b': (typeof _PageBRoute)['_outputType']; '/page-c': (typeof _PageCRoute)['_outputType']; } }Understand the Granite project structure
mainA standard Granite project follows this structure:
pages/: Contains screen files. Each file in this directory becomes a route/screen in your app (e.g.,index.tsxis the home screen).src/: Core source code._app.tsx: The main microservice entry point for shared logic across all screens.router.gen.ts: Auto-generated file providing type-safe routing.
granite.config.ts: The main configuration file for your Granite app.react-native.config.js: React Native specific settings.require.context.ts: Auto-generated routing context.
Use ImpressionArea to detect component visibility
mainThe
ImpressionAreacomponent detects when its child component becomes visible on the screen and triggers callbacks. This is useful for logging impressions, triggering animations, or managing resource usage when a component enters or leaves the viewport.Important Requirements:
- By default,
ImpressionAreamust be used inside anIOScrollViewto function correctly. - If you use it outside of
IOScrollView, you must set theUNSAFE__impressFallbackOnMountprop totrueto detect visibility based on the component's mount time. Failing to do this while outside anIOScrollViewwill result in anIOProviderMissingError.
import { ImpressionArea, IOScrollView } from '@granite-js/react-native'; <IOScrollView> <ImpressionArea onImpressionStart={() => console.log('Visible!')} onImpressionEnd={() => console.log('Hidden!')} > <MyComponent /> </ImpressionArea> </IOScrollView>- By default,