[{"data":1,"prerenderedAt":898},["ShallowReactive",2],{"page:\u002Fdocs\u002F5.x\u002Fintegrations\u002Fopenapi-import":3},{"id":4,"title":5,"body":6,"description":880,"extension":881,"frontmatter":882,"heading":5,"meta":889,"navigation":891,"order":886,"path":892,"seo":893,"sitemap":894,"source":895,"stem":896,"__hash__":897},"docs\u002Fdocs\u002F5.x\u002Fintegrations\u002Fopenapi-import.md","Import an OpenAPI spec in TypeScript with openapi-import",{"type":7,"value":8,"toc":869},"minimark",[9,25,71,83,95,366,370,376,394,494,512,516,541,607,610,802,814,818,838,842],[10,11,12,20,21,24],"p",{},[13,14,16],"a",{"href":15},"https:\u002F\u002Fgithub.com\u002Fkubb-labs\u002Fopenapi-import",[17,18,19],"code",{},"openapi-import"," lets you import a spec like a TypeScript module and get the output of every plugin in your ",[17,22,23],{},"kubb.config.ts",", without generated files:",[26,27,31],"pre",{"language":28,"code":29,"class":30},"ts","import { type Pet, petStatusEnum } from '.\u002FpetStore.openapi.yaml'","highlights",[17,32,34],{"class":33},"language-ts",[35,36,39,43,47,50,54,57,61,64,67],"span",{"class":37,"style":38},"line","display: inline",[35,40,42],{"style":41},"color:#d73a49;--hls-dark:#f97583","import ",[35,44,46],{"style":45},"color:#005cc5;--hls-dark:#79b8ff","{ ",[35,48,49],{"style":41},"type ",[35,51,53],{"style":52},"color:#6f42c1;--hls-dark:#b392f0","Pet",[35,55,56],{"style":41},", ",[35,58,60],{"style":59},"color:#24292e;--hls-dark:#e1e4e8","petStatusEnum ",[35,62,63],{"style":45},"} ",[35,65,66],{"style":41},"from ",[35,68,70],{"style":69},"color:#032f62;--hls-dark:#9ecbff","'.\u002FpetStore.openapi.yaml'",[10,72,73,74,78,79,82],{},"It is a ",[13,75,77],{"href":76},"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftypescript-go\u002Fpull\u002F4712","TypeScript content mapper",", so ",[17,80,81],{},"tsc"," and your editor type-check the plugin output in place of the spec. Go to definition, hover, and rename jump between the generated types and the keys in the spec.",[84,85,87,88,90,91,94],"blockquote",{"as":86},"warning","",[17,89,19],{}," is experimental. It needs TypeScript 7.1.0-beta or later with ",[17,92,93],{},"--runExternalCode",".",[96,97,99,104,107,151,155,166,320,324,351,360],"steps",{"level":98},"2",[100,101,103],"h2",{"id":102},"install-openapi-import","Install openapi-import",[10,105,106],{},"Install it with Kubb and the TypeScript beta:",[108,109,111,133],"code-group",{"sync":110},"package-manager",[26,112,116],{"language":113,"filename":114,"code":115,"class":30},"shell","pnpm","pnpm add -D kubb openapi-import typescript@beta",[17,117,119],{"class":118},"language-shell",[35,120,121,124,127,130],{"class":37,"style":38},[35,122,123],{"style":52},"pnpm ",[35,125,126],{"style":59},"add -D kubb openapi-import typescript",[35,128,129],{"style":59},"@",[35,131,132],{"style":59},"beta",[26,134,137],{"language":113,"filename":135,"code":136,"class":30},"npm","npm install -D kubb openapi-import typescript@beta",[17,138,139],{"class":118},[35,140,141,144,147,149],{"class":37,"style":38},[35,142,143],{"style":52},"npm ",[35,145,146],{"style":59},"install -D kubb openapi-import typescript",[35,148,129],{"style":59},[35,150,132],{"style":59},[100,152,154],{"id":153},"register-the-extension","Register the extension",[10,156,157,158,161,162,165],{},"Add the content mapper to ",[17,159,160],{},"tsconfig.json",", and name the spec ",[17,163,164],{},"\u003Cname>.openapi.yaml",":",[26,167,170],{"language":168,"filename":160,"code":169,"class":30},"json","{\n  \"compilerOptions\": {\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Bundler\",\n    \"strict\": true,\n    \"noEmit\": true\n  },\n  \"contentMappers\": [{ \"package\": \"openapi-import\", \"extensions\": [\".openapi.yaml\", \".openapi.yml\"] }],\n  \"include\": [\".\u002Fsrc\u002F**\u002F*\"]\n}",[17,171,173,178,179,178,192,178,208,178,222,178,236,178,247,178,256,178,299,178,316],{"class":172},"language-json",[35,174,175],{"class":37,"style":38},[35,176,177],{"style":45},"{","\n",[35,180,181,184,187,190],{"class":37,"style":38},[35,182,183],{"style":45},"  ",[35,185,186],{"style":45},"\"compilerOptions\"",[35,188,189],{"style":41},": ",[35,191,177],{"style":45},[35,193,194,197,200,202,205],{"class":37,"style":38},[35,195,196],{"style":45},"    ",[35,198,199],{"style":45},"\"module\"",[35,201,189],{"style":41},[35,203,204],{"style":69},"\"ESNext\"",[35,206,207],{"style":41},",",[35,209,210,212,215,217,220],{"class":37,"style":38},[35,211,196],{"style":41},[35,213,214],{"style":45},"\"moduleResolution\"",[35,216,189],{"style":41},[35,218,219],{"style":69},"\"Bundler\"",[35,221,207],{"style":41},[35,223,224,226,229,231,234],{"class":37,"style":38},[35,225,196],{"style":41},[35,227,228],{"style":45},"\"strict\"",[35,230,189],{"style":41},[35,232,233],{"style":45},"true",[35,235,207],{"style":41},[35,237,238,240,243,245],{"class":37,"style":38},[35,239,196],{"style":41},[35,241,242],{"style":45},"\"noEmit\"",[35,244,189],{"style":41},[35,246,233],{"style":45},[35,248,249,251,254],{"class":37,"style":38},[35,250,183],{"style":45},[35,252,253],{"style":45},"}",[35,255,207],{"style":41},[35,257,258,260,263,265,268,271,273,276,278,281,283,286,289,291,294,297],{"class":37,"style":38},[35,259,183],{"style":41},[35,261,262],{"style":45},"\"contentMappers\"",[35,264,189],{"style":41},[35,266,267],{"style":45},"[{ ",[35,269,270],{"style":45},"\"package\"",[35,272,189],{"style":41},[35,274,275],{"style":69},"\"openapi-import\"",[35,277,56],{"style":41},[35,279,280],{"style":45},"\"extensions\"",[35,282,189],{"style":41},[35,284,285],{"style":45},"[",[35,287,288],{"style":69},"\".openapi.yaml\"",[35,290,56],{"style":41},[35,292,293],{"style":69},"\".openapi.yml\"",[35,295,296],{"style":45},"] }]",[35,298,207],{"style":41},[35,300,301,303,306,308,310,313],{"class":37,"style":38},[35,302,183],{"style":41},[35,304,305],{"style":45},"\"include\"",[35,307,189],{"style":41},[35,309,285],{"style":45},[35,311,312],{"style":69},"\".\u002Fsrc\u002F**\u002F*\"",[35,314,315],{"style":45},"]",[35,317,318],{"class":37,"style":38},[35,319,253],{"style":45},[100,321,323],{"id":322},"run-the-type-check","Run the type check",[108,325,326,338],{"sync":110},[26,327,329],{"language":113,"filename":114,"code":328,"class":30},"pnpm tsc --noEmit --runExternalCode",[17,330,331],{"class":118},[35,332,333,335],{"class":37,"style":38},[35,334,123],{"style":52},[35,336,337],{"style":59},"tsc --noEmit --runExternalCode",[26,339,341],{"language":113,"filename":135,"code":340,"class":30},"node node_modules\u002Ftypescript\u002Fbin\u002Ftsc --noEmit --runExternalCode",[17,342,343],{"class":118},[35,344,345,348],{"class":37,"style":38},[35,346,347],{"style":52},"node ",[35,349,350],{"style":59},"node_modules\u002Ftypescript\u002Fbin\u002Ftsc --noEmit --runExternalCode",[10,352,353,354,356,357,94],{},"With npm, a bare ",[17,355,81],{}," runs TypeScript 6, so call the binary from ",[17,358,359],{},"typescript",[10,361,362,363,365],{},"VS Code only passes ",[17,364,93],{}," in trusted workspaces.",[100,367,369],{"id":368},"choose-the-plugins","Choose the plugins",[10,371,372,373,375],{},"Add a ",[17,374,23],{}," to set plugin options or to run other plugins, and install each plugin it imports:",[26,377,380],{"language":113,"filename":378,"code":379,"class":30},"Terminal","pnpm add -D @kubb\u002Fplugin-ts",[17,381,382],{"class":118},[35,383,384,386,389,391],{"class":37,"style":38},[35,385,123],{"style":52},[35,387,388],{"style":59},"add -D ",[35,390,129],{"style":59},[35,392,393],{"style":59},"kubb\u002Fplugin-ts",[26,395,397],{"language":28,"filename":23,"code":396,"class":30},"import { pluginTs } from '@kubb\u002Fplugin-ts'\nimport { defineConfig } from 'kubb\u002Fconfig'\n\nexport default defineConfig({\n  output: { path: '.\u002Fsrc\u002Fgen' },\n  plugins: [pluginTs()],\n})",[17,398,399,178,415,178,431,178,433,178,447,178,470,178,489],{"class":33},[35,400,401,403,405,408,410,412],{"class":37,"style":38},[35,402,42],{"style":41},[35,404,46],{"style":45},[35,406,407],{"style":59},"pluginTs ",[35,409,63],{"style":45},[35,411,66],{"style":41},[35,413,414],{"style":69},"'@kubb\u002Fplugin-ts'",[35,416,417,419,421,424,426,428],{"class":37,"style":38},[35,418,42],{"style":41},[35,420,46],{"style":45},[35,422,423],{"style":59},"defineConfig ",[35,425,63],{"style":45},[35,427,66],{"style":41},[35,429,430],{"style":69},"'kubb\u002Fconfig'",[35,432],{"class":37,"style":38},[35,434,435,438,441,444],{"class":37,"style":38},[35,436,437],{"style":41},"export ",[35,439,440],{"style":41},"default ",[35,442,443],{"style":52},"defineConfig",[35,445,446],{"style":45},"({",[35,448,449,451,454,456,458,461,463,466,468],{"class":37,"style":38},[35,450,183],{"style":45},[35,452,453],{"style":45},"output",[35,455,189],{"style":41},[35,457,46],{"style":45},[35,459,460],{"style":45},"path",[35,462,189],{"style":41},[35,464,465],{"style":69},"'.\u002Fsrc\u002Fgen' ",[35,467,253],{"style":45},[35,469,207],{"style":41},[35,471,472,474,477,479,481,484,487],{"class":37,"style":38},[35,473,183],{"style":41},[35,475,476],{"style":45},"plugins",[35,478,189],{"style":41},[35,480,285],{"style":45},[35,482,483],{"style":52},"pluginTs",[35,485,486],{"style":45},"()]",[35,488,207],{"style":41},[35,490,491],{"class":37,"style":38},[35,492,493],{"style":45},"})",[10,495,496,497,500,501,504,505,507,508,511],{},"Add ",[17,498,499],{},".\u002Fkubb.config.ts"," to ",[17,502,503],{},"include"," in ",[17,506,160],{},". The mapper finds the config like the CLI does and reloads it when it changes. With several configs, a spec uses the one whose ",[17,509,510],{},"input"," matches it.",[100,513,515],{"id":514},"load-the-spec-at-run-time","Load the spec at run time",[10,517,518,519,522,523,526,527,531,532,535,536,538,539,165],{},"TypeScript does not emit the spec to JavaScript, so values such as ",[17,520,521],{},"petStatusEnum"," need a bundler. Add ",[17,524,525],{},"kubb()"," from any ",[13,528,530],{"href":529},"\u002Fdocs\u002F5.x\u002Fintegrations\u002Foverview#build-tools","build tool integration"," without a ",[17,533,534],{},"config"," option, so it reads the same ",[17,537,23],{}," as ",[17,540,81],{},[26,542,545],{"language":28,"filename":543,"code":544,"class":30},"vite.config.ts","import kubb from 'kubb\u002Fvite'\nimport { defineConfig } from 'vite'\n\nexport default defineConfig({\n  plugins: [kubb()],\n})",[17,546,547,178,559,178,574,178,576,178,586,178,603],{"class":33},[35,548,549,551,554,556],{"class":37,"style":38},[35,550,42],{"style":41},[35,552,553],{"style":59},"kubb ",[35,555,66],{"style":41},[35,557,558],{"style":69},"'kubb\u002Fvite'",[35,560,561,563,565,567,569,571],{"class":37,"style":38},[35,562,42],{"style":41},[35,564,46],{"style":45},[35,566,423],{"style":59},[35,568,63],{"style":45},[35,570,66],{"style":41},[35,572,573],{"style":69},"'vite'",[35,575],{"class":37,"style":38},[35,577,578,580,582,584],{"class":37,"style":38},[35,579,437],{"style":41},[35,581,440],{"style":41},[35,583,443],{"style":52},[35,585,446],{"style":45},[35,587,588,590,592,594,596,599,601],{"class":37,"style":38},[35,589,183],{"style":45},[35,591,476],{"style":45},[35,593,189],{"style":41},[35,595,285],{"style":45},[35,597,598],{"style":52},"kubb",[35,600,486],{"style":45},[35,602,207],{"style":41},[35,604,605],{"class":37,"style":38},[35,606,493],{"style":45},[10,608,609],{},"The types and the values then come from the same import:",[26,611,614],{"language":28,"filename":612,"code":613,"class":30},"src\u002Fpets.ts","import { type GetPetByIdPath, type GetPetByIdResponse, petStatusEnum } from '..\u002FpetStore.openapi.yaml'\n\nexport async function getAvailablePet({ petId }: GetPetByIdPath): Promise\u003CGetPetByIdResponse | undefined> {\n  const response = await fetch(`https:\u002F\u002Fpetstore3.swagger.io\u002Fapi\u002Fv3\u002Fpet\u002F${petId}`)\n  const pet: GetPetByIdResponse = await response.json()\n\n  return pet.status === petStatusEnum.available ? pet : undefined\n}",[17,615,616,178,645,178,647,178,697,178,735,178,762,178,764,178,798],{"class":33},[35,617,618,620,622,624,627,629,631,634,636,638,640,642],{"class":37,"style":38},[35,619,42],{"style":41},[35,621,46],{"style":45},[35,623,49],{"style":41},[35,625,626],{"style":52},"GetPetByIdPath",[35,628,56],{"style":41},[35,630,49],{"style":41},[35,632,633],{"style":52},"GetPetByIdResponse",[35,635,56],{"style":41},[35,637,60],{"style":59},[35,639,63],{"style":45},[35,641,66],{"style":41},[35,643,644],{"style":69},"'..\u002FpetStore.openapi.yaml'",[35,646],{"class":37,"style":38},[35,648,649,651,654,657,660,663,666,668,670,672,675,677,680,683,686,689,692,695],{"class":37,"style":38},[35,650,437],{"style":41},[35,652,653],{"style":41},"async ",[35,655,656],{"style":41},"function ",[35,658,659],{"style":52},"getAvailablePet",[35,661,662],{"style":45},"({ ",[35,664,665],{"style":59},"petId ",[35,667,253],{"style":45},[35,669,189],{"style":59},[35,671,626],{"style":52},[35,673,674],{"style":45},")",[35,676,189],{"style":59},[35,678,679],{"style":52},"Promise",[35,681,682],{"style":41},"\u003C",[35,684,685],{"style":52},"GetPetByIdResponse ",[35,687,688],{"style":41},"| ",[35,690,691],{"style":45},"undefined",[35,693,694],{"style":41},"> ",[35,696,177],{"style":45},[35,698,699,701,704,707,710,713,716,719,722,725,728,730,733],{"class":37,"style":38},[35,700,183],{"style":45},[35,702,703],{"style":41},"const ",[35,705,706],{"style":59},"response ",[35,708,709],{"style":41},"= ",[35,711,712],{"style":41},"await ",[35,714,715],{"style":52},"fetch",[35,717,718],{"style":45},"(",[35,720,721],{"style":69},"`https:\u002F\u002Fpetstore3.swagger.io\u002Fapi\u002Fv3\u002Fpet\u002F",[35,723,724],{"style":59},"${",[35,726,727],{"style":59},"petId",[35,729,253],{"style":59},[35,731,732],{"style":69},"`",[35,734,674],{"style":45},[35,736,737,739,741,744,746,748,750,752,755,757,759],{"class":37,"style":38},[35,738,183],{"style":45},[35,740,703],{"style":41},[35,742,743],{"style":59},"pet",[35,745,189],{"style":59},[35,747,685],{"style":52},[35,749,709],{"style":41},[35,751,712],{"style":41},[35,753,754],{"style":59},"response",[35,756,94],{"style":41},[35,758,168],{"style":52},[35,760,761],{"style":45},"()",[35,763],{"class":37,"style":38},[35,765,766,768,771,773,775,778,781,783,785,788,791,794,796],{"class":37,"style":38},[35,767,183],{"style":45},[35,769,770],{"style":41},"return ",[35,772,743],{"style":59},[35,774,94],{"style":41},[35,776,777],{"style":45},"status ",[35,779,780],{"style":41},"=== ",[35,782,521],{"style":59},[35,784,94],{"style":41},[35,786,787],{"style":45},"available ",[35,789,790],{"style":41},"? ",[35,792,793],{"style":59},"pet ",[35,795,189],{"style":41},[35,797,691],{"style":45},[35,799,800],{"class":37,"style":38},[35,801,253],{"style":45},[10,803,804,805,807,808,810,811,813],{},"A config with an ",[17,806,510],{}," also writes the generated files at build time. Leave ",[17,809,510],{}," out to import specs only. The bundler reads ",[17,812,23],{}," once, so restart it after you change the config.",[100,815,817],{"id":816},"limits","Limits",[819,820,821,829,835],"ul",{},[822,823,824,825,828],"li",{},"Code a plugin writes to a separate file, such as a bundled client runtime, is not included. Point imports like the client's ",[17,826,827],{},"importPath"," at a package.",[822,830,831,832,834],{},"Files that ",[17,833,23],{}," imports are not watched. Restart the TypeScript server after you change them.",[822,836,837],{},"A changed spec runs a full Kubb build: about 0.4 s for a 10 KB spec and 2.6 s for a 1.4 MB spec.",[100,839,841],{"id":840},"see-also","See also",[819,843,844,849,855,861],{},[822,845,846],{},[13,847,848],{"href":529},"Build tool integrations",[822,850,851],{},[13,852,854],{"href":853},"\u002Fdocs\u002F5.x\u002Fintegrations\u002Fvite","Vite integration",[822,856,857],{},[13,858,860],{"href":859},"\u002Fdocs\u002F5.x\u002Freference\u002Fconfiguration","Configuration reference",[822,862,863,868],{},[13,864,865,867],{"href":15},[17,866,19],{}," on GitHub",", with a working pet-store example",{"title":87,"searchDepth":870,"depth":870,"links":871},5,[872,874,875,876,877,878,879],{"id":102,"depth":873,"text":103},2,{"id":153,"depth":873,"text":154},{"id":322,"depth":873,"text":323},{"id":368,"depth":873,"text":369},{"id":514,"depth":873,"text":515},{"id":816,"depth":873,"text":817},{"id":840,"depth":873,"text":841},"Import a .openapi.yaml spec in TypeScript with openapi-import and get the types and enums your kubb.config.ts generates, without generated files.","md",{"layout":883,"title":5,"description":880,"outline":884,"order":886,"navigation":887},"doc",[873,885],3,15,{"title":19,"icon":888},"i-simple-icons-typescript",{"layout":883,"outline":890},[873,885],{"title":19,"icon":888},"\u002Fdocs\u002F5.x\u002Fintegrations\u002Fopenapi-import",{"title":5,"description":880},{"loc":892},"kubb-labs\u002Fkubb\u002Fdocs\u002F5.x\u002Fintegrations\u002Fopenapi-import.md","docs\u002F5.x\u002Fintegrations\u002Fopenapi-import","07bm8erVYD2Vzq6DiUEI4IM3XH1glNn0f6lDRsxHt-c",1792931641623]