[{"data":1,"prerenderedAt":2005},["ShallowReactive",2],{"navigation_docs_en":3,"-en-concepts-architecture":342,"-en-concepts-architecture-surround":2000},[4,45,61,96,132,166,196,217,241,265],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Coming from Laravel","\u002Fen\u002Fgetting-started\u002Fcoming-from-laravel","en\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Coming from Symfony","\u002Fen\u002Fgetting-started\u002Fcoming-from-symfony","en\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Installation","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Your first module","\u002Fen\u002Fgetting-started\u002Ffirst-module","en\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Project structure","\u002Fen\u002Fgetting-started\u002Fproject-structure","en\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"The shop sample application","\u002Fen\u002Fgetting-started\u002Fsample-app","en\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Reference","i-lucide-book-open","\u002Fen\u002Freference","en\u002F10.reference",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Configuration","\u002Fen\u002Freference\u002Fconfiguration","en\u002F10.reference\u002F1.configuration","i-lucide-settings",{"title":57,"path":58,"stem":59,"icon":60},"External dependencies","\u002Fen\u002Freference\u002Fdependencies","en\u002F10.reference\u002F2.dependencies","i-lucide-package",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":44},"Concepts","i-lucide-lightbulb","\u002Fen\u002Fconcepts","en\u002F2.concepts",[67,72,77,82,86,91],{"title":68,"path":69,"stem":70,"icon":71},"Architecture","\u002Fen\u002Fconcepts\u002Farchitecture","en\u002F2.concepts\u002F1.architecture","i-lucide-layers",{"title":73,"path":74,"stem":75,"icon":76},"Application lifecycle","\u002Fen\u002Fconcepts\u002Fapplication-lifecycle","en\u002F2.concepts\u002F2.application-lifecycle","i-lucide-power",{"title":78,"path":79,"stem":80,"icon":81},"Error model","\u002Fen\u002Fconcepts\u002Ferror-model","en\u002F2.concepts\u002F3.error-model","i-lucide-shield-alert",{"title":52,"path":83,"stem":84,"icon":85},"\u002Fen\u002Fconcepts\u002Fconfiguration","en\u002F2.concepts\u002F4.configuration","i-lucide-settings-2",{"title":87,"path":88,"stem":89,"icon":90},"Codegen pipeline","\u002Fen\u002Fconcepts\u002Fcodegen-pipeline","en\u002F2.concepts\u002F5.codegen-pipeline","i-lucide-file-json",{"title":92,"path":93,"stem":94,"icon":95},"Design patterns","\u002Fen\u002Fconcepts\u002Fdesign-patterns","en\u002F2.concepts\u002F6.design-patterns","i-lucide-puzzle",{"title":97,"icon":98,"path":99,"stem":100,"children":101,"page":44},"HTTP & Routing","i-lucide-globe","\u002Fen\u002Fhttp","en\u002F3.http",[102,107,112,117,122,127],{"title":103,"path":104,"stem":105,"icon":106},"The server core","\u002Fen\u002Fhttp\u002Fserver","en\u002F3.http\u002F1.server","i-lucide-server",{"title":108,"path":109,"stem":110,"icon":111},"The Fiber engine","\u002Fen\u002Fhttp\u002Ffiber","en\u002F3.http\u002F2.fiber","i-lucide-zap",{"title":113,"path":114,"stem":115,"icon":116},"The chi engine","\u002Fen\u002Fhttp\u002Fchi","en\u002F3.http\u002F3.chi","i-lucide-route",{"title":118,"path":119,"stem":120,"icon":121},"Error responses","\u002Fen\u002Fhttp\u002Ferror-responses","en\u002F3.http\u002F4.error-responses","i-lucide-octagon-alert",{"title":123,"path":124,"stem":125,"icon":126},"Validation","\u002Fen\u002Fhttp\u002Fvalidation","en\u002F3.http\u002F5.validation","i-lucide-badge-check",{"title":128,"path":129,"stem":130,"icon":131},"Pagination","\u002Fen\u002Fhttp\u002Fpagination","en\u002F3.http\u002F6.pagination","i-lucide-list-ordered",{"title":133,"icon":134,"path":135,"stem":136,"children":137,"page":44},"Database","i-lucide-database","\u002Fen\u002Fdatabase","en\u002F4.database",[138,142,147,151,156,161],{"title":139,"path":140,"stem":141,"icon":134},"Overview","\u002Fen\u002Fdatabase\u002Foverview","en\u002F4.database\u002F1.overview",{"title":143,"path":144,"stem":145,"icon":146},"pgx","\u002Fen\u002Fdatabase\u002Fpgx","en\u002F4.database\u002F2.pgx","i-lucide-plug",{"title":148,"path":149,"stem":150,"icon":71},"bun","\u002Fen\u002Fdatabase\u002Fbun","en\u002F4.database\u002F3.bun",{"title":152,"path":153,"stem":154,"icon":155},"Transactions","\u002Fen\u002Fdatabase\u002Ftransactions","en\u002F4.database\u002F4.transactions","i-lucide-git-merge",{"title":157,"path":158,"stem":159,"icon":160},"Migrations","\u002Fen\u002Fdatabase\u002Fmigrations","en\u002F4.database\u002F5.migrations","i-lucide-file-stack",{"title":162,"path":163,"stem":164,"icon":165},"Seeders","\u002Fen\u002Fdatabase\u002Fseeding","en\u002F4.database\u002F6.seeding","i-lucide-sprout",{"title":167,"icon":168,"path":169,"stem":170,"children":171,"page":44},"Async & Background","i-lucide-workflow","\u002Fen\u002Fasync","en\u002F5.async",[172,176,181,186,191],{"title":173,"path":174,"stem":175,"icon":131},"Queue","\u002Fen\u002Fasync\u002Fqueue","en\u002F5.async\u002F1.queue",{"title":177,"path":178,"stem":179,"icon":180},"Events","\u002Fen\u002Fasync\u002Fevents","en\u002F5.async\u002F2.events","i-lucide-radio",{"title":182,"path":183,"stem":184,"icon":185},"Outbox","\u002Fen\u002Fasync\u002Foutbox","en\u002F5.async\u002F3.outbox","i-lucide-inbox",{"title":187,"path":188,"stem":189,"icon":190},"Scheduling","\u002Fen\u002Fasync\u002Fscheduler","en\u002F5.async\u002F4.scheduler","i-lucide-calendar-clock",{"title":192,"path":193,"stem":194,"icon":195},"Worker","\u002Fen\u002Fasync\u002Fworker","en\u002F5.async\u002F5.worker","i-lucide-cog",{"title":197,"icon":198,"path":199,"stem":200,"children":201,"page":44},"Security","i-lucide-shield-check","\u002Fen\u002Fsecurity","en\u002F6.security",[202,207,212],{"title":203,"path":204,"stem":205,"icon":206},"Authentication","\u002Fen\u002Fsecurity\u002Fauthentication","en\u002F6.security\u002F1.authentication","i-lucide-key-round",{"title":208,"path":209,"stem":210,"icon":211},"RBAC","\u002Fen\u002Fsecurity\u002Frbac","en\u002F6.security\u002F2.rbac","i-lucide-users",{"title":213,"path":214,"stem":215,"icon":216},"Policies","\u002Fen\u002Fsecurity\u002Fpolicies","en\u002F6.security\u002F3.policies","i-lucide-gavel",{"title":218,"icon":219,"path":220,"stem":221,"children":222,"page":44},"Observability","i-lucide-activity","\u002Fen\u002Fobservability","en\u002F7.observability",[223,226,231,236],{"title":139,"path":224,"stem":225,"icon":219},"\u002Fen\u002Fobservability\u002Foverview","en\u002F7.observability\u002F1.overview",{"title":227,"path":228,"stem":229,"icon":230},"Logging","\u002Fen\u002Fobservability\u002Flogging","en\u002F7.observability\u002F2.logging","i-lucide-scroll-text",{"title":232,"path":233,"stem":234,"icon":235},"OpenTelemetry","\u002Fen\u002Fobservability\u002Fopentelemetry","en\u002F7.observability\u002F3.opentelemetry","i-lucide-radar",{"title":237,"path":238,"stem":239,"icon":240},"Sentry","\u002Fen\u002Fobservability\u002Fsentry","en\u002F7.observability\u002F4.sentry","i-lucide-bug",{"title":242,"icon":243,"path":244,"stem":245,"children":246,"page":44},"Storage & Mail","i-lucide-hard-drive","\u002Fen\u002Fstorage-mail","en\u002F8.storage-mail",[247,251,256,261],{"title":248,"path":249,"stem":250,"icon":243},"Storage","\u002Fen\u002Fstorage-mail\u002Fstorage","en\u002F8.storage-mail\u002F1.storage",{"title":252,"path":253,"stem":254,"icon":255},"Email","\u002Fen\u002Fstorage-mail\u002Fmail","en\u002F8.storage-mail\u002F2.mail","i-lucide-mail",{"title":257,"path":258,"stem":259,"icon":260},"Notifications","\u002Fen\u002Fstorage-mail\u002Fnotifications","en\u002F8.storage-mail\u002F3.notifications","i-lucide-bell",{"title":262,"path":263,"stem":264,"icon":180},"Realtime","\u002Fen\u002Fstorage-mail\u002Frealtime","en\u002F8.storage-mail\u002F4.realtime",{"title":266,"icon":267,"path":268,"stem":269,"children":270,"page":44},"CLI Reference","i-lucide-terminal","\u002Fen\u002Fcli","en\u002F9.cli",[271,274,279,284,289,294,299,303,308,313,318,323,328,333,337],{"title":139,"path":272,"stem":273,"icon":267},"\u002Fen\u002Fcli\u002Foverview","en\u002F9.cli\u002F1.overview",{"title":275,"path":276,"stem":277,"icon":278},"add db","\u002Fen\u002Fcli\u002Fadd-db","en\u002F9.cli\u002F10.add-db","i-lucide-database-zap",{"title":280,"path":281,"stem":282,"icon":283},"add compose \u002F add docker","\u002Fen\u002Fcli\u002Fadd-compose","en\u002F9.cli\u002F11.add-compose","i-lucide-container",{"title":285,"path":286,"stem":287,"icon":288},"add mail","\u002Fen\u002Fcli\u002Fadd-mail","en\u002F9.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":290,"path":291,"stem":292,"icon":293},"add notification","\u002Fen\u002Fcli\u002Fadd-notification","en\u002F9.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":295,"path":296,"stem":297,"icon":298},"add realtime","\u002Fen\u002Fcli\u002Fadd-realtime","en\u002F9.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":300,"path":301,"stem":302,"icon":165},"add seeder","\u002Fen\u002Fcli\u002Fadd-seeder","en\u002F9.cli\u002F15.add-seeder",{"title":304,"path":305,"stem":306,"icon":307},"new project","\u002Fen\u002Fcli\u002Fnew-project","en\u002F9.cli\u002F2.new-project","i-lucide-folder-plus",{"title":309,"path":310,"stem":311,"icon":312},"new module","\u002Fen\u002Fcli\u002Fnew-module","en\u002F9.cli\u002F3.new-module","i-lucide-blocks",{"title":314,"path":315,"stem":316,"icon":317},"add surface","\u002Fen\u002Fcli\u002Fadd-surface","en\u002F9.cli\u002F4.add-surface","i-lucide-layers-2",{"title":319,"path":320,"stem":321,"icon":322},"add core","\u002Fen\u002Fcli\u002Fadd-core","en\u002F9.cli\u002F5.add-core","i-lucide-box",{"title":324,"path":325,"stem":326,"icon":327},"add handler","\u002Fen\u002Fcli\u002Fadd-handler","en\u002F9.cli\u002F6.add-handler","i-lucide-webhook",{"title":329,"path":330,"stem":331,"icon":332},"new migration","\u002Fen\u002Fcli\u002Fnew-migration","en\u002F9.cli\u002F7.new-migration","i-lucide-file-plus",{"title":334,"path":335,"stem":336,"icon":195},"worker generators","\u002Fen\u002Fcli\u002Fworker-generators","en\u002F9.cli\u002F8.worker-generators",{"title":338,"path":339,"stem":340,"icon":341},"upgrade templates","\u002Fen\u002Fcli\u002Fupgrade-templates","en\u002F9.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"id":343,"title":68,"body":344,"description":1993,"extension":1994,"links":1995,"meta":1996,"navigation":1997,"path":69,"seo":1998,"stem":70,"__hash__":1999},"docs_en\u002Fen\u002F2.concepts\u002F1.architecture.md",{"type":345,"value":346,"toc":1971},"minimark",[347,373,378,383,444,448,538,541,597,601,682,686,752,755,825,829,862,866,891,902,906,933,1119,1134,1138,1141,1216,1233,1237,1244,1625,1636,1640,1643,1678,1682,1685,1761,1765,1774,1778,1781,1900,1922,1926,1967],[348,349,350,351,355,356,359,360,367,368,372],"p",{},"The library half of gpsystem is not a monolithic framework but a collection of ",[352,353,354],"strong",{},"Go packages organized into eight capability groups",". Each package is usable, and understandable, on its own; this page gives you the map: what lives where, what builds on what, and the principle the whole thing is assembled by. Its role in this sense is a ",[352,357,358],{},"microservice chassis"," (",[361,362,366],"a",{"href":363,"rel":364},"https:\u002F\u002Fmicroservices.io\u002Fpatterns\u002Fmicroservice-chassis.html",[365],"nofollow","Richardson","): cross-cutting infrastructure (lifecycle, HTTP layer, telemetry, error model) that you import as a library. There is no container and no facade invisibly stitching the parts together: whatever connects, connects in your ",[369,370,371],"code",{},"main.go",", in explicit code.",[374,375,377],"h2",{"id":376},"package-map","Package map",[379,380,382],"h3",{"id":381},"foundations","Foundations",[384,385,386,399],"table",{},[387,388,389],"thead",{},[390,391,392,396],"tr",{},[393,394,395],"th",{},"Package",[393,397,398],{},"What it gives you",[400,401,402,416,432],"tbody",{},[390,403,404,410],{},[405,406,407],"td",{},[369,408,409],{},"errs",[405,411,412,413,415],{},"stackable errors with a machine-readable code and a client-safe message (",[361,414,78],{"href":79},")",[390,417,418,423],{},[405,419,420],{},[369,421,422],{},"envconf",[405,424,425,426,429,430,415],{},"typed configuration from env variables, with ",[369,427,428],{},".env"," support (",[361,431,52],{"href":83},[390,433,434,439],{},[405,435,436],{},[369,437,438],{},"app",[405,440,441,442,415],{},"the signal-driven graceful-shutdown process lifecycle every chassis sits on (",[361,443,73],{"href":74},[379,445,447],{"id":446},"http-layer","HTTP layer",[384,449,450,458],{},[387,451,452],{},[390,453,454,456],{},[393,455,395],{},[393,457,398],{},[400,459,460,476,489,502,514,526],{},[390,461,462,467],{},[405,463,464],{},[369,465,466],{},"server",[405,468,469,470,359,473,415],{},"the engine-agnostic core: the shared ",[369,471,472],{},"server.Config",[361,474,475],{"href":104},"HTTP server",[390,477,478,483],{},[405,479,480],{},[369,481,482],{},"server\u002Ffiberx",[405,484,485,486,415],{},"the Fiber v3 engine (",[361,487,488],{"href":109},"Fiber",[390,490,491,496],{},[405,492,493],{},[369,494,495],{},"server\u002Fchix",[405,497,498,499,415],{},"the chi \u002F net\u002Fhttp engine (",[361,500,501],{"href":114},"chi",[390,503,504,509],{},[405,505,506],{},[369,507,508],{},"httperr",[405,510,511,512,415],{},"RFC 9457 problem+json error responses, with a single mapping (",[361,513,118],{"href":119},[390,515,516,521],{},[405,517,518],{},[369,519,520],{},"validate",[405,522,523,524,415],{},"struct-tag-based request validation (",[361,525,123],{"href":124},[390,527,528,533],{},[405,529,530],{},[369,531,532],{},"paginate",[405,534,535,536,415],{},"offset and cursor pagination types and helpers (",[361,537,128],{"href":129},[379,539,197],{"id":540},"security",[384,542,543,551],{},[387,544,545],{},[390,546,547,549],{},[393,548,395],{},[393,550,398],{},[400,552,553,565,585],{},[390,554,555,560],{},[405,556,557],{},[369,558,559],{},"auth",[405,561,562,563,415],{},"JWT issuing and middleware (",[361,564,203],{"href":204},[390,566,567,572],{},[405,568,569],{},[369,570,571],{},"rbac",[405,573,574,575,578,579,582,583,415],{},"role- and permission-based access (",[369,576,577],{},"RequireRole",", ",[369,580,581],{},"RequirePermission",") (",[361,584,208],{"href":209},[390,586,587,592],{},[405,588,589],{},[369,590,591],{},"policy",[405,593,594,595,415],{},"per-request policies, fail-closed enforcer middleware (",[361,596,213],{"href":214},[379,598,600],{"id":599},"database-storage","Database & storage",[384,602,603,611],{},[387,604,605],{},[390,606,607,609],{},[393,608,395],{},[393,610,398],{},[400,612,613,635,651,663],{},[390,614,615,620],{},[405,616,617],{},[369,618,619],{},"dbx",[405,621,622,623,626,627,630,631,578,633,415],{},"the shared ",[369,624,625],{},"dbx.Config"," and the ",[369,628,629],{},"Transactor"," interface (",[361,632,133],{"href":140},[361,634,152],{"href":153},[390,636,637,642],{},[405,638,639],{},[369,640,641],{},"dbx\u002Fpg",[405,643,644,645,648,649,415],{},"pgx-based access: pool, context-resolving ",[369,646,647],{},"DB",", transactor (",[361,650,143],{"href":144},[390,652,653,658],{},[405,654,655],{},[369,656,657],{},"dbx\u002Fbunx",[405,659,660,661,415],{},"the bun query builder over the same pool and transaction semantics (",[361,662,148],{"href":149},[390,664,665,674],{},[405,666,667,670,671,415],{},[369,668,669],{},"storage"," (+",[369,672,673],{},"storage\u002Fs3",[405,675,676,677,630,680,415],{},"object storage behind the ",[369,678,679],{},"storage.Store",[361,681,248],{"href":249},[379,683,685],{"id":684},"async-processing","Async processing",[384,687,688,696],{},[387,689,690],{},[390,691,692,694],{},[393,693,395],{},[393,695,398],{},[400,697,698,710,727,740],{},[390,699,700,705],{},[405,701,702],{},[369,703,704],{},"queue",[405,706,707,708,415],{},"asynq + Redis: task enqueueing and options (",[361,709,173],{"href":174},[390,711,712,720],{},[405,713,714,670,717,415],{},[369,715,716],{},"events",[369,718,719],{},"events\u002Foutbox",[405,721,722,723,578,725,415],{},"events with listener fan-out; transactional outbox dispatcher and relay (",[361,724,177],{"href":178},[361,726,182],{"href":183},[390,728,729,734],{},[405,730,731],{},[369,732,733],{},"scheduler",[405,735,736,737,415],{},"cron\u002Finterval scheduling with replica-safe leader election (",[361,738,739],{"href":188},"Scheduler",[390,741,742,747],{},[405,743,744],{},[369,745,746],{},"worker",[405,748,749,750,415],{},"the background-processing chassis: asynq server + relay + scheduler in one binary (",[361,751,192],{"href":193},[379,753,218],{"id":754},"observability",[384,756,757,765],{},[387,758,759],{},[390,760,761,763],{},[393,762,395],{},[393,764,398],{},[400,766,767,783,798,810],{},[390,768,769,774],{},[405,770,771],{},[369,772,773],{},"telemetry",[405,775,776,777,780,781,415],{},"the facade: ",[369,778,779],{},"telemetry.Setup"," boots all three in one call (",[361,782,139],{"href":224},[390,784,785,793],{},[405,786,787,670,790,415],{},[369,788,789],{},"logx",[369,791,792],{},"logx\u002Fmonolog",[405,794,795,796,415],{},"the default slog logger's composition; a Monolog-style dev console format (",[361,797,227],{"href":228},[390,799,800,805],{},[405,801,802],{},[369,803,804],{},"otelx",[405,806,807,808,415],{},"pure OpenTelemetry SDK bootstrap: traces, metrics, an OTLP log bridge (",[361,809,232],{"href":233},[390,811,812,817],{},[405,813,814],{},[369,815,816],{},"sentryx",[405,818,819,820,359,823,415],{},"the optional Sentry integration, gated on ",[369,821,822],{},"SENTRY_DSN",[361,824,237],{"href":238},[379,826,828],{"id":827},"mail","Mail",[384,830,831,839],{},[387,832,833],{},[390,834,835,837],{},[393,836,395],{},[393,838,398],{},[400,840,841],{},[390,842,843,853],{},[405,844,845,670,847,578,850,415],{},[369,846,827],{},[369,848,849],{},"mail\u002Fsmtp",[369,851,852],{},"mail\u002Fmjml",[405,854,855,856,859,860,415],{},"a ",[369,857,858],{},"Mailer"," interface, a message builder, MJML template rendering (",[361,861,828],{"href":253},[379,863,865],{"id":864},"tooling","Tooling",[384,867,868,876],{},[387,869,870],{},[390,871,872,874],{},[393,873,395],{},[393,875,398],{},[400,877,878],{},[390,879,880,885],{},[405,881,882],{},[369,883,884],{},"cmd\u002Fgpsystem",[405,886,887,888,415],{},"the scaffolding CLI: project, module, surface, handler and worker generators (",[361,889,890],{"href":272},"CLI",[348,892,893,894,897,898,901],{},"The generators and templates live in the kit's ",[369,895,896],{},"internal\u002F",". Consumer projects only ever see their output, plus the ",[361,899,900],{"href":88},"TypeSpec→OpenAPI→server-code pipeline",".",[374,903,905],{"id":904},"the-lifecycle-of-a-service","The lifecycle of a service",[348,907,908,909,911,912,914,915,920,921,924,925,928,929,932],{},"The ",[369,910,466],{}," package itself only provides ",[369,913,472],{},"; the process lifecycle lives in the ",[361,916,917,919],{"href":74},[369,918,438],{}," package",", and the engines (",[369,922,923],{},"fiberx.Run"," and ",[369,926,927],{},"chix.Run",") delegate to the same ",[369,930,931],{},"app.Run",". The sequence is therefore identical regardless of engine:",[934,935,937,942,975,979,982,1033,1037,1052,1056,1071,1075,1078,1108],"steps",{"level":936},"4",[938,939,941],"h4",{"id":940},"telemetry-bootstrap","Telemetry bootstrap",[348,943,944,946,947,949,950,952,953,955,956,959,960,963,964,966,967,970,971,974],{},[369,945,779],{}," boots observability in one call: Sentry first (",[369,948,816],{},", if ",[369,951,822],{}," is set), then the OTel SDK (",[369,954,804],{},": resource, OTLP exporters selected by the standard ",[369,957,958],{},"OTEL_*"," env variables, W3C propagation), and finally the default ",[369,961,962],{},"slog"," logger (",[369,965,789],{},": OTLP bridge + console handler + Sentry handler in one fanout). With ",[369,968,969],{},"OTEL_DEV_MODE=true"," it runs without exporters, logging readable console output. Skip the whole step with the ",[369,972,973],{},"WithoutTelemetry()"," option.",[938,976,978],{"id":977},"app-router-construction","App \u002F router construction",[348,980,981],{},"The engine comes up with the kit defaults wired in:",[983,984,985,1000,1009,1027],"ul",{},[986,987,988,991,992,995,996,999],"li",{},[352,989,990],{},"error rendering",": on Fiber, ",[369,993,994],{},"httperr.NewErrorHandler"," is the app's ",[369,997,998],{},"ErrorHandler","; on chi, the router itself writes RFC 9457 Problems for panics, 404 and 405",[986,1001,1002,1005,1006,1008],{},[352,1003,1004],{},"panic recovery",": on both engines a recovered panic becomes an ",[369,1007,409],{}," error whose stack points at the panic site",[986,1010,1011,991,1014,995,1017,359,1020,1023,1024,415],{},[352,1012,1013],{},"validation",[369,1015,1016],{},"validate.New()",[369,1018,1019],{},"StructValidator",[369,1021,1022],{},"c.Bind()"," validates automatically); on chi, validation runs in the generated strict pipeline (",[369,1025,1026],{},"chix.StrictValidator",[986,1028,1029,1030],{},"the OTel HTTP middleware, a per-request Sentry hub, CORS and the body limit, then whatever you pass via ",[369,1031,1032],{},"WithMiddleware(...)",[938,1034,1036],{"id":1035},"route-registration","Route registration",[348,1038,1039,1040,1043,1044,1047,1048,1051],{},"Your ",[369,1041,1042],{},"register"," callback mounts the modules: on Fiber you get a ",[369,1045,1046],{},"*fiber.App",", on chi a ",[369,1049,1050],{},"chi.Router",", and you work with the native API: groups, routes, engine middleware.",[938,1053,1055],{"id":1054},"listen-signal-handling","Listen + signal handling",[348,1057,1058,1059,1062,1063,1066,1067,1070],{},"The listen call runs in a goroutine; ",[369,1060,1061],{},"signal.NotifyContext"," watches ",[369,1064,1065],{},"SIGINT","\u002F",[369,1068,1069],{},"SIGTERM",". Cancelling the parent context also triggers shutdown, which is useful in tests.",[938,1072,1074],{"id":1073},"graceful-shutdown","Graceful shutdown",[348,1076,1077],{},"On signal, in strict order:",[1079,1080,1081,1091,1101],"ol",{},[986,1082,1083,1084,1087,1088],{},"shutdown with ",[369,1085,1086],{},"ShutdownTimeout",": no new requests, ",[352,1089,1090],{},"in-flight requests finish",[986,1092,1093,1096,1097,1100],{},[369,1094,1095],{},"WithCloser"," closers run in ",[352,1098,1099],{},"LIFO"," order (whatever you opened last closes first)",[986,1102,1103,1104,1107],{},"telemetry flushes ",[352,1105,1106],{},"last",", so spans emitted by closers still export",[348,1109,1110,1111,1114,1115,1118],{},"A second signal kills the process immediately. ",[369,1112,1113],{},"Run"," returns ",[369,1116,1117],{},"nil"," on a clean shutdown.",[348,1120,908,1121,359,1124,1127,1128,1130,1131,1133],{},[361,1122,1123],{"href":193},"worker chassis",[369,1125,1126],{},"worker.Run",") is built on exactly the same ",[369,1129,931],{},": instead of HTTP, it shuts down an asynq server, the outbox relay and the schedule runner in the same order. The ",[361,1132,73],{"href":74}," page describes the internals in detail.",[379,1135,1137],{"id":1136},"options","Options",[348,1139,1140],{},"The two engines' option sets mirror each other:",[384,1142,1143,1153],{},[387,1144,1145],{},[390,1146,1147,1150],{},[393,1148,1149],{},"Option",[393,1151,1152],{},"Use",[400,1154,1155,1165,1175,1197,1207],{},[390,1156,1157,1162],{},[405,1158,1159],{},[369,1160,1161],{},"WithCloser(name, fn)",[405,1163,1164],{},"register cleanup (pgx pool, queue consumer, ...)",[390,1166,1167,1172],{},[405,1168,1169],{},[369,1170,1171],{},"WithMiddleware(mw...)",[405,1173,1174],{},"app-level middleware after the kit defaults",[390,1176,1177,1187],{},[405,1178,1179,1182,1183,1186],{},[369,1180,1181],{},"WithConfig(fn)"," (fiberx) \u002F ",[369,1184,1185],{},"WithHTTPServer(fn)"," (chix)",[405,1188,1189,1190,1193,1194],{},"escape hatch: mutate the ",[369,1191,1192],{},"fiber.Config"," \u002F ",[369,1195,1196],{},"http.Server",[390,1198,1199,1204],{},[405,1200,1201],{},[369,1202,1203],{},"WithValidator(v)",[405,1205,1206],{},"custom validator (e.g. extra validation tags)",[390,1208,1209,1213],{},[405,1210,1211],{},[369,1212,973],{},[405,1214,1215],{},"tests, or processes that configure OTel themselves",[1217,1218,1219,1220,1193,1223,1226,1227,1193,1229,1232],"tip",{},"For tests, ",[369,1221,1222],{},"fiberx.New(cfg, opts...)",[369,1224,1225],{},"chix.New(cfg, opts...)"," return the configured ",[369,1228,1046],{},[369,1230,1231],{},"*chi.Mux"," without running them.",[374,1234,1236],{"id":1235},"centralize-dont-abstract","Centralize, don't abstract",[348,1238,1239,1240,1243],{},"The kit's design principle: access to external dependencies is ",[352,1241,1242],{},"concentrated in one kit package each, but their types flow freely through the public API",". There is no \"gpsystem router interface\" and no \"gpsystem query abstraction\". The signatures openly carry the third-party types:",[1245,1246,1251],"pre",{"className":1247,"code":1248,"language":1249,"meta":1250,"style":1250},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F server\u002Ffiberx: register receives a *fiber.App\nfunc Run(ctx context.Context, cfg server.Config, register func(app *fiber.App) error, opts ...Option) error\n\n\u002F\u002F server\u002Fchix: register receives a chi.Router\nfunc Run(ctx context.Context, cfg server.Config, register func(r chi.Router) error, opts ...Option) error\n\n\u002F\u002F dbx\u002Fpg: hands you a raw pgxpool.Pool and pgx types\nfunc MustNewPool(ctx context.Context, cfg dbx.Config) *pgxpool.Pool\nfunc (d *DB) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)\n\n\u002F\u002F dbx\u002Fbunx: hands you a *bun.DB over the same pool\nfunc Open(pool *pgxpool.Pool) *bun.DB\n\n\u002F\u002F worker: the escape hatch hands you raw asynq\nfunc WithMux(fn func(mux *asynq.ServeMux)) Option\n","go","",[369,1252,1253,1262,1345,1352,1358,1418,1423,1429,1470,1536,1541,1547,1580,1585,1591],{"__ignoreMap":1250},[1254,1255,1258],"span",{"class":1256,"line":1257},"line",1,[1254,1259,1261],{"class":1260},"sHwdD","\u002F\u002F server\u002Ffiberx: register receives a *fiber.App\n",[1254,1263,1265,1269,1273,1276,1280,1284,1286,1289,1292,1295,1298,1300,1303,1305,1308,1311,1313,1316,1319,1321,1324,1326,1330,1332,1335,1338,1340,1342],{"class":1256,"line":1264},2,[1254,1266,1268],{"class":1267},"sMK4o","func",[1254,1270,1272],{"class":1271},"s2Zo4"," Run",[1254,1274,1275],{"class":1267},"(",[1254,1277,1279],{"class":1278},"sHdIc","ctx",[1254,1281,1283],{"class":1282},"sBMFI"," context",[1254,1285,901],{"class":1267},[1254,1287,1288],{"class":1282},"Context",[1254,1290,1291],{"class":1267},",",[1254,1293,1294],{"class":1278}," cfg",[1254,1296,1297],{"class":1282}," server",[1254,1299,901],{"class":1267},[1254,1301,1302],{"class":1282},"Config",[1254,1304,1291],{"class":1267},[1254,1306,1307],{"class":1278}," register",[1254,1309,1310],{"class":1267}," func(",[1254,1312,438],{"class":1278},[1254,1314,1315],{"class":1267}," *",[1254,1317,1318],{"class":1282},"fiber",[1254,1320,901],{"class":1267},[1254,1322,1323],{"class":1282},"App",[1254,1325,415],{"class":1267},[1254,1327,1329],{"class":1328},"spNyl"," error",[1254,1331,1291],{"class":1267},[1254,1333,1334],{"class":1278}," opts",[1254,1336,1337],{"class":1267}," ...",[1254,1339,1149],{"class":1282},[1254,1341,415],{"class":1267},[1254,1343,1344],{"class":1328}," error\n",[1254,1346,1348],{"class":1256,"line":1347},3,[1254,1349,1351],{"emptyLinePlaceholder":1350},true,"\n",[1254,1353,1355],{"class":1256,"line":1354},4,[1254,1356,1357],{"class":1260},"\u002F\u002F server\u002Fchix: register receives a chi.Router\n",[1254,1359,1361,1363,1365,1367,1369,1371,1373,1375,1377,1379,1381,1383,1385,1387,1389,1391,1394,1397,1399,1402,1404,1406,1408,1410,1412,1414,1416],{"class":1256,"line":1360},5,[1254,1362,1268],{"class":1267},[1254,1364,1272],{"class":1271},[1254,1366,1275],{"class":1267},[1254,1368,1279],{"class":1278},[1254,1370,1283],{"class":1282},[1254,1372,901],{"class":1267},[1254,1374,1288],{"class":1282},[1254,1376,1291],{"class":1267},[1254,1378,1294],{"class":1278},[1254,1380,1297],{"class":1282},[1254,1382,901],{"class":1267},[1254,1384,1302],{"class":1282},[1254,1386,1291],{"class":1267},[1254,1388,1307],{"class":1278},[1254,1390,1310],{"class":1267},[1254,1392,1393],{"class":1278},"r",[1254,1395,1396],{"class":1282}," chi",[1254,1398,901],{"class":1267},[1254,1400,1401],{"class":1282},"Router",[1254,1403,415],{"class":1267},[1254,1405,1329],{"class":1328},[1254,1407,1291],{"class":1267},[1254,1409,1334],{"class":1278},[1254,1411,1337],{"class":1267},[1254,1413,1149],{"class":1282},[1254,1415,415],{"class":1267},[1254,1417,1344],{"class":1328},[1254,1419,1421],{"class":1256,"line":1420},6,[1254,1422,1351],{"emptyLinePlaceholder":1350},[1254,1424,1426],{"class":1256,"line":1425},7,[1254,1427,1428],{"class":1260},"\u002F\u002F dbx\u002Fpg: hands you a raw pgxpool.Pool and pgx types\n",[1254,1430,1432,1434,1437,1439,1441,1443,1445,1447,1449,1451,1454,1456,1458,1460,1462,1465,1467],{"class":1256,"line":1431},8,[1254,1433,1268],{"class":1267},[1254,1435,1436],{"class":1271}," MustNewPool",[1254,1438,1275],{"class":1267},[1254,1440,1279],{"class":1278},[1254,1442,1283],{"class":1282},[1254,1444,901],{"class":1267},[1254,1446,1288],{"class":1282},[1254,1448,1291],{"class":1267},[1254,1450,1294],{"class":1278},[1254,1452,1453],{"class":1282}," dbx",[1254,1455,901],{"class":1267},[1254,1457,1302],{"class":1282},[1254,1459,415],{"class":1267},[1254,1461,1315],{"class":1267},[1254,1463,1464],{"class":1282},"pgxpool",[1254,1466,901],{"class":1267},[1254,1468,1469],{"class":1282},"Pool\n",[1254,1471,1473,1475,1477,1480,1483,1485,1487,1490,1492,1494,1496,1498,1500,1502,1505,1508,1510,1513,1515,1518,1520,1522,1524,1526,1529,1531,1533],{"class":1256,"line":1472},9,[1254,1474,1268],{"class":1267},[1254,1476,359],{"class":1267},[1254,1478,1479],{"class":1278},"d ",[1254,1481,1482],{"class":1267},"*",[1254,1484,647],{"class":1282},[1254,1486,415],{"class":1267},[1254,1488,1489],{"class":1271}," Query",[1254,1491,1275],{"class":1267},[1254,1493,1279],{"class":1278},[1254,1495,1283],{"class":1282},[1254,1497,901],{"class":1267},[1254,1499,1288],{"class":1282},[1254,1501,1291],{"class":1267},[1254,1503,1504],{"class":1278}," sql",[1254,1506,1507],{"class":1328}," string",[1254,1509,1291],{"class":1267},[1254,1511,1512],{"class":1278}," args",[1254,1514,1337],{"class":1267},[1254,1516,1517],{"class":1282},"any",[1254,1519,415],{"class":1267},[1254,1521,359],{"class":1267},[1254,1523,143],{"class":1282},[1254,1525,901],{"class":1267},[1254,1527,1528],{"class":1282},"Rows",[1254,1530,1291],{"class":1267},[1254,1532,1329],{"class":1328},[1254,1534,1535],{"class":1267},")\n",[1254,1537,1539],{"class":1256,"line":1538},10,[1254,1540,1351],{"emptyLinePlaceholder":1350},[1254,1542,1544],{"class":1256,"line":1543},11,[1254,1545,1546],{"class":1260},"\u002F\u002F dbx\u002Fbunx: hands you a *bun.DB over the same pool\n",[1254,1548,1550,1552,1555,1557,1560,1562,1564,1566,1569,1571,1573,1575,1577],{"class":1256,"line":1549},12,[1254,1551,1268],{"class":1267},[1254,1553,1554],{"class":1271}," Open",[1254,1556,1275],{"class":1267},[1254,1558,1559],{"class":1278},"pool",[1254,1561,1315],{"class":1267},[1254,1563,1464],{"class":1282},[1254,1565,901],{"class":1267},[1254,1567,1568],{"class":1282},"Pool",[1254,1570,415],{"class":1267},[1254,1572,1315],{"class":1267},[1254,1574,148],{"class":1282},[1254,1576,901],{"class":1267},[1254,1578,1579],{"class":1282},"DB\n",[1254,1581,1583],{"class":1256,"line":1582},13,[1254,1584,1351],{"emptyLinePlaceholder":1350},[1254,1586,1588],{"class":1256,"line":1587},14,[1254,1589,1590],{"class":1260},"\u002F\u002F worker: the escape hatch hands you raw asynq\n",[1254,1592,1594,1596,1599,1601,1604,1606,1609,1611,1614,1616,1619,1622],{"class":1256,"line":1593},15,[1254,1595,1268],{"class":1267},[1254,1597,1598],{"class":1271}," WithMux",[1254,1600,1275],{"class":1267},[1254,1602,1603],{"class":1278},"fn",[1254,1605,1310],{"class":1267},[1254,1607,1608],{"class":1278},"mux",[1254,1610,1315],{"class":1267},[1254,1612,1613],{"class":1282},"asynq",[1254,1615,901],{"class":1267},[1254,1617,1618],{"class":1282},"ServeMux",[1254,1620,1621],{"class":1267},"))",[1254,1623,1624],{"class":1282}," Option\n",[348,1626,1627,1628,359,1631,1635],{},"This is deliberate. The Fiber, chi, pgx, bun and asynq documentation, Stack Overflow answers and upstream sample code all apply to your project verbatim. You are not learning a kit-specific wrapper API, you are learning the Go ecosystem's established libraries, curated in one place. The generated project, in this sense, is a ",[352,1629,1630],{},"service template",[361,1632,366],{"href":1633,"rel":1634},"https:\u002F\u002Fmicroservices.io\u002Fpatterns\u002Fservice-template.html",[365],"): runnable scaffolding you're handed and that's yours from that point on, not a runtime layer living above your app.",[379,1637,1639],{"id":1638},"the-three-deliberate-exceptions","The three deliberate exceptions",[348,1641,1642],{},"In three places the kit does hide the dependency behind an interface, each time for a stated reason:",[983,1644,1645,1652,1668],{},[986,1646,1647,1651],{},[361,1648,1649],{"href":249},[369,1650,679],{}," hides the AWS SDK: your app code should not have to import the AWS SDK to upload a file, and the implementation (AWS, MinIO, RustFS) is swappable via env configuration.",[986,1653,1654,1658,1659,1661,1662,1664,1665,1667],{},[361,1655,1656],{"href":238},[369,1657,816],{}," wraps sentry-go: Sentry is switchable from the environment (",[369,1660,822],{}," empty = fully off, every hook a no-op), and nothing outside the ",[369,1663,773],{}," facade imports it: a consumer of ",[369,1666,804],{}," alone (a CLI, a migration tool) never even links sentry-go into its binary.",[986,1669,1670,1674,1675,1677],{},[361,1671,1672],{"href":253},[369,1673,827],{},"'s ",[369,1676,858],{}," interface fronts go-mail and mjml-go, so tests can swap in an in-memory mailer.",[379,1679,1681],{"id":1680},"swappable-and-omittable-parts","Swappable and omittable parts",[348,1683,1684],{},"The other side of centralizing is that the parts don't fuse together:",[983,1686,1687,1703,1712,1722,1745],{},[986,1688,1689,1698,1699,1702],{},[352,1690,1691,1066,1693,1695,1696],{},[369,1692,619],{},[369,1694,641],{}," work without ",[369,1697,466],{},": a CLI tool or the ",[369,1700,1701],{},"cmd\u002Fmigrate"," binary uses the same pool and transactor with no HTTP layer.",[986,1704,1705,1708,1709,1711],{},[352,1706,1707],{},"Sentry is fully omittable",": with ",[369,1710,822],{}," empty the integration is dead code.",[986,1713,1714,359,1717,1719,1720,901],{},[352,1715,1716],{},"OTel runs without exporters in dev mode",[369,1718,969],{},"), or is skipped entirely with ",[369,1721,973],{},[986,1723,1724,359,1727,1730,1731,1736,1737,1740,1741,1744],{},[352,1725,1726],{},"The engine is chosen per project",[369,1728,1729],{},"new project --engine fiber|chi",", recorded in ",[361,1732,1733],{"href":88},[369,1734,1735],{},"gpsystem.yaml","); business code (handler, service, repository) is engine-independent, only the entry point, ",[369,1738,1739],{},"register.go"," and the generated ",[369,1742,1743],{},"gen\u002F"," package differ.",[986,1746,1747,1750,1751,1753,1754,1756,1757,1760],{},[352,1748,1749],{},"The DB implementation is decided by import",": a repository imports ",[369,1752,641],{}," (SQL) or ",[369,1755,657],{}," (query builder); the ",[369,1758,1759],{},"dbx.Transactor"," interface and the context-carried transaction are shared.",[379,1762,1764],{"id":1763},"where-the-line-is","Where the line is",[348,1766,1767,1768,1773],{},"The kit deliberately doesn't introduce a few things that would tip it toward framework territory (",[361,1769,1772],{"href":1770,"rel":1771},"https:\u002F\u002Fmartinfowler.com\u002Fbliki\u002FInversionOfControl.html",[365],"Fowler: Inversion of Control","): no Module interface that a bootstrap discovers and orders; no kit-owned lifecycle hook inside business code; no runtime DI container resolving the dependency graph for you. If any of those showed up, the honest name from that point on would be \"framework,\" not \"toolkit\"; this is a deliberate guardrail, not an accidental omission.",[374,1775,1777],{"id":1776},"shared-code-a-decision-ladder","Shared code: a decision ladder",[348,1779,1780],{},"Every project eventually needs code used by more than one surface, or more than one module. Where it goes depends on how widely it's actually shared. It's a decision ladder, not a single rule:",[934,1782,1783,1787,1794,1798,1809,1813,1838,1842,1886,1890],{"level":936},[938,1784,1786],{"id":1785},"surface-local","Surface-local",[348,1788,1789,1790,1793],{},"Used by one surface only → keep it inside that surface's ",[369,1791,1792],{},"service"," package. Don't extract it just because it looks reusable; extract it when a second caller actually appears.",[938,1795,1797],{"id":1796},"module-core","Module core",[348,1799,1800,1801,1804,1805,1808],{},"A business rule or entity used by several surfaces of one module → the module's generated ",[369,1802,1803],{},"core\u002F"," package. This is the default, generated home of shared rules: every module gets it alongside its first surface, and the surface services delegate to it. Its persistence counterpart is the module-level ",[369,1806,1807],{},"repository\u002F",": one persistence layer per module, shared by every surface.",[938,1810,1812],{"id":1811},"module-level","Module-level",[348,1814,1815,1816,1066,1819,1822,1823,1826,1827,1830,1831,1834,1835,1837],{},"Not a business rule but content the module produces, used by the ",[369,1817,1818],{},"jobs",[369,1820,1821],{},"listeners"," units or by several surfaces → a named sibling package under ",[369,1824,1825],{},"internal\u002Fmodules\u002F\u003Cmodule>\u002F",", e.g. ",[369,1828,1829],{},"internal\u002Fmodules\u002Fcontact\u002Fmail\u002F",". Never call it ",[369,1832,1833],{},"shared\u002F",": name it for what it provides, the same rule that applies to any Go package (see ",[361,1836,92],{"href":93},").",[938,1839,1841],{"id":1840},"app-wide","App-wide",[348,1843,1844,1845,1848,1849,1852,1853,1856,1857,1860,1861,1864,1865,1868,1869,1872,1873,578,1876,578,1879,1882,1883,901],{},"Used by two or more modules, or by ",[369,1846,1847],{},"cmd\u002F*"," wiring itself → ",[369,1850,1851],{},"internal\u002Fplatform\u002F\u003Cname>\u002F",". This is the only app-wide shared location a generated project has; there is no ",[369,1854,1855],{},"pkg\u002F"," and no ",[369,1858,1859],{},"internal\u002Fpkg\u002F"," (see ",[361,1862,35],{"href":1863},"\u002Fen\u002Fgetting-started\u002Fproject-structure#where-does-shared-code-go","). ",[369,1866,1867],{},"internal\u002Fplatform"," may hold: env-config composition, infrastructure adapters and factories, framework glue, small cross-cutting technical helpers (request language, request ID). It must ",[352,1870,1871],{},"not"," hold: business entities, business rules, or module-specific templates and payloads; that content stays at the module rungs, further down this ladder. As at every other level, the naming rule holds: no ",[369,1874,1875],{},"util",[369,1877,1878],{},"common",[369,1880,1881],{},"helpers"," or ",[369,1884,1885],{},"shared",[938,1887,1889],{"id":1888},"kit-level","Kit-level",[348,1891,1892,1893,1066,1896,1899],{},"Project-agnostic, and genuinely needed by a second project → promote it into the gpsystem kit itself. The kit plays the role Go's own layout guides call a ",[369,1894,1895],{},"foundation",[369,1897,1898],{},"pkg"," layer: code with zero project-specific knowledge. Promotion needs a second real consumer: promoting on the first use freezes an app-specific decision into the kit's public API before it's actually general.",[348,1901,1902,1903,1066,1905,1907,1908,1910,1911,1914,1915,1918,1919,1921],{},"A worked example of the whole ladder: the kit's ",[369,1904,827],{},[369,1906,849],{}," packages are the transport (kit-level: every project needs an SMTP client). A module's recipient list and email templates are business content (module-level: ",[369,1909,1829],{},"). Composed ",[369,1912,1913],{},"MAIL_*"," config lives in ",[369,1916,1917],{},"internal\u002Fplatform\u002Fconfig",". See ",[361,1920,828],{"href":253}," for the full example.",[374,1923,1925],{"id":1924},"where-to-next","Where to next",[983,1927,1928,1934,1941,1952,1957,1962],{},[986,1929,908,1930,1933],{},[361,1931,1932],{"href":41},"shop sample app"," shows how all of this composes into a project: entry points, worker, events.",[986,1935,1936,1938,1939,901],{},[361,1937,73],{"href":74}," opens up the inside of ",[369,1940,931],{},[986,1942,1943,1945,1946,1948,1949,1951],{},[361,1944,78],{"href":79}," follows the ",[369,1947,409],{}," → ",[369,1950,508],{}," chain end to end.",[986,1953,1954,1956],{},[361,1955,87],{"href":88}," takes you from TypeSpec to generated server code.",[986,1958,1959,1961],{},[361,1960,92],{"href":93}," catalogs the recurring design patterns across the packages above, with code and external sources.",[986,1963,1964,1966],{},[361,1965,57],{"href":58}," lists every underlying library with its version and official documentation.",[1968,1969,1970],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":1250,"searchDepth":1264,"depth":1264,"links":1972},[1973,1983,1986,1991,1992],{"id":376,"depth":1264,"text":377,"children":1974},[1975,1976,1977,1978,1979,1980,1981,1982],{"id":381,"depth":1347,"text":382},{"id":446,"depth":1347,"text":447},{"id":540,"depth":1347,"text":197},{"id":599,"depth":1347,"text":600},{"id":684,"depth":1347,"text":685},{"id":754,"depth":1347,"text":218},{"id":827,"depth":1347,"text":828},{"id":864,"depth":1347,"text":865},{"id":904,"depth":1264,"text":905,"children":1984},[1985],{"id":1136,"depth":1347,"text":1137},{"id":1235,"depth":1264,"text":1236,"children":1987},[1988,1989,1990],{"id":1638,"depth":1347,"text":1639},{"id":1680,"depth":1347,"text":1681},{"id":1763,"depth":1347,"text":1764},{"id":1776,"depth":1264,"text":1777},{"id":1924,"depth":1264,"text":1925},"The kit's package map, the lifecycle of a service, and the principle that holds it together.","md",null,{},{"icon":71},{"title":68,"description":1993},"zPGpYVNW2P3gje29VNSy_ks_nem3B8XIr7RqZSUnT48",[2001,2003],{"title":57,"path":58,"stem":59,"description":2002,"icon":60,"children":-1},"Every underlying library, its version, its role, and its official documentation, grouped by category.",{"title":73,"path":74,"stem":75,"description":2004,"icon":76,"children":-1},"The app package: the signal-driven graceful shutdown every gpsystem binary sits on.",1784668706297]