
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Napper — CLI-First API Testing for VS Code, Zed and Any Editor</title>
  <subtitle>The developer-first HTTP testing tool from Nimblesite. Native CLI binaries, a VS Code extension, and a portable language server. As simple as curl for one-off requests, scales to full test suites with scripting in your language — JavaScript, Python, F#, or C#.</subtitle>
  <link href="https://napperapi.dev/feed.xml" rel="self"/>
  <link href="https://napperapi.dev/"/>
  <updated>2026-02-27T00:00:00.000Z</updated>
  <id>https://napperapi.dev/</id>
  <author><name>Christian Findlay</name></author>
  <entry>
    <title>Introducing Napper: CLI-First API Testing, Scripted in Your Language</title>
    <link href="https://napperapi.dev/blog/introducing-napper/"/>
    <id>https://napperapi.dev/blog/introducing-napper/</id>
    <updated>2026-02-27T00:00:00.000Z</updated>
    <content type="html">https://napperapi.dev/%3Ch1%20id=%22introducing-napper-cli-first-api-testing-scripted-in-your-language%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#introducing-napper-cli-first-api-testing-scripted-in-your-language%22%3EIntroducing%20Napper:%20CLI-First%20API%20Testing,%20Scripted%20in%20Your%20Language%3C/a%3E%3C/h1%3E%3Cp%3EAPI%20testing%20tools%20have%20a%20problem.%20They&#39;re%20either%20too%20simple%20(%3Ca%20href=%22/docs/vs-http-files/%22%3E.http%20files%3C/a%3E%20with%20no%20assertions%20and%20no%20CLI)%20or%20too%20heavy%20(%3Ca%20href=%22/docs/vs-postman/%22%3EPostman%3C/a%3E%20with%20its%20mandatory%20accounts,%20cloud%20sync,%20and%20paid%20tiers).%20%3Ca%20href=%22/docs/vs-bruno/%22%3EBruno%3C/a%3E%20moved%20the%20needle%20with%20git-friendly%20collections,%20but%20it&#39;s%20still%20a%20GUI-first%20tool%20with%20sandboxed%20JavaScript.%3C/p%3E%3Cp%3E%3Cstrong%3E%3Ca%20href=%22https://github.com/Nimblesite/napper%22%3ENapper%3C/a%3E%3C/strong%3E%20takes%20a%20different%20approach.%20It&#39;s%20a%20free,%20open-source%20API%20testing%20tool%20for%20%3Cem%3Eanyone%3C/em%3E%20testing%20APIs:%20the%20CLI%20is%20the%20primary%20interface,%20everything%20is%20stored%20as%20plain%20text,%20and%20you%20script%20in%20the%20language%20you%20already%20use%20%E2%80%94%20%3Cstrong%3EJavaScript,%20Python,%20F#,%20or%20C#%3C/strong%3E%20%E2%80%94%20on%20a%20real%20runtime,%20with%20no%20sandbox.%20Napper%20ships%20as%20a%20self-contained%20native%20binary%20(not%20a%20.NET%20DLL)%20and%20edits%20natively%20in%20%3Ca%20href=%22https://code.visualstudio.com/%22%3EVS%20Code%3C/a%3E,%20%3Ca%20href=%22https://zed.dev/%22%3EZed%3C/a%3E,%20the%20VS%20Code-compatible%20editors%20Cursor,%20Windsurf,%20and%20Antigravity,%20and%20any%20editor%20via%20a%20portable%20language%20server.%3C/p%3E%3Ch2%20id=%22the-cli-is-the-product%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#the-cli-is-the-product%22%3EThe%20CLI%20is%20the%20product%3C/a%3E%3C/h2%3E%3Cp%3ENapper%20is%20not%20a%20GUI%20with%20a%20CLI%20bolted%20on.%20The%20command%20line%20is%20the%20primary%20interface.%20Every%20feature%20works%20from%20the%20terminal%20first,%20then%20from%20%3Ca%20href=%22https://code.visualstudio.com/%22%3EVS%20Code%3C/a%3E%20second.%3C/p%3E%3Cpre%20class=%22language-bash%22%3E%3Ccode%20class=%22language-bash%22%3E%3Cspan%20class=%22token%20comment%22%3E#%20Run%20a%20single%20request%3C/span%3Enapper%20run%20./health.nap%3Cspan%20class=%22token%20comment%22%3E#%20Run%20a%20full%20test%20suite%3C/span%3Enapper%20run%20./smoke.naplist%3Cspan%20class=%22token%20comment%22%3E#%20Run%20with%20a%20specific%20environment%20and%20JUnit%20XML%20output%20for%20CI/CD%3C/span%3Enapper%20run%20./tests/%20%3Cspan%20class=%22token%20parameter%20variable%22%3E--env%3C/span%3E%20staging%20%3Cspan%20class=%22token%20parameter%20variable%22%3E--output%3C/span%3E%20junit%20%3Cspan%20class=%22token%20operator%22%3E%3E%3C/span%3E%20results.xml%3C/code%3E%3C/pre%3E%3Cp%3EThe%20CLI%20binary%20is%20self-contained%20with%20no%20runtime%20dependencies.%20It%20runs%20on%20Windows,%20macOS,%20and%20Linux.%20Install%20it%20with%20%3Ca%20href=%22https://brew.sh%22%3EHomebrew%3C/a%3E%20(%3Ccode%3Ebrew%20tap%20Nimblesite/tap%20&amp;amp;&amp;amp;%20brew%20install%20napper%3C/code%3E)%20or%20%3Ca%20href=%22https://scoop.sh%22%3EScoop%3C/a%3E%20(%3Ccode%3Escoop%20bucket%20add%20Nimblesite%20https://github.com/Nimblesite/scoop-bucket%20&amp;amp;&amp;amp;%20scoop%20install%20napper%3C/code%3E),%20or%20download%20it%20from%20%3Ca%20href=%22https://github.com/Nimblesite/napper/releases%22%3EGitHub%20Releases%3C/a%3E.%3C/p%3E%3Ch2%20id=%22plain-text-everything--git-friendly-by-design%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#plain-text-everything--git-friendly-by-design%22%3EPlain%20text%20everything%20%E2%80%94%20git-friendly%20by%20design%3C/a%3E%3C/h2%3E%3Cp%3EEvery%20request%20is%20a%20%3Ca%20href=%22/docs/nap-files/%22%3E.nap%20file%3C/a%3E.%20Every%20test%20suite%20is%20a%20%3Ca%20href=%22/docs/naplist-files/%22%3E.naplist%20file%3C/a%3E.%20Every%20environment%20is%20a%20%3Ca%20href=%22/docs/environments/%22%3E.napenv%20file%3C/a%3E.%20All%20plain%20text.%20All%20in%20your%20repo.%20Diffs%20are%20readable.%20Code%20reviews%20are%20meaningful.%20No%20binary%20blobs,%20no%20JSON%20dumps,%20no%20proprietary%20formats.%3C/p%3E%3Cp%3EHere&#39;s%20what%20a%20%3Ccode%3E.nap%3C/code%3E%20file%20looks%20like:%3C/p%3E%3Cpre%3E%3Ccode%3E[meta]name%20=%20Create%20a%20new%20posttags%20=%20posts,%20crud[request]method%20=%20POSTurl%20=%20{{baseUrl}}/posts[request.headers]Content-Type%20=%20application/jsonAuthorization%20=%20Bearer%20{{token}}[request.body]&amp;quot;&amp;quot;&amp;quot;{%20%20&amp;quot;title&amp;quot;:%20&amp;quot;Nap%20Integration%20Test&amp;quot;,%20%20&amp;quot;body&amp;quot;:%20&amp;quot;Created%20by%20Napper&amp;quot;,%20%20&amp;quot;userId&amp;quot;:%201}&amp;quot;&amp;quot;&amp;quot;[assert]status%20=%20201body.id%20existsbody.title%20=%20Nap%20Integration%20Testduration%20&amp;lt;%202s%3C/code%3E%3C/pre%3E%3Cp%3EThat&#39;s%20a%20complete%20HTTP%20request%20with%20headers,%20a%20JSON%20body,%20and%20%3Ca%20href=%22/docs/assertions/%22%3Edeclarative%20assertions%3C/a%3E%20%E2%80%94%20all%20in%20one%20readable%20file.%20No%20scripting%20needed%20for%20the%20common%20cases.%3C/p%3E%3Ch2%20id=%22scripting-in-your-language--real-runtimes-no-sandbox%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#scripting-in-your-language--real-runtimes-no-sandbox%22%3EScripting%20in%20your%20language%20%E2%80%94%20real%20runtimes,%20no%20sandbox%3C/a%3E%3C/h2%3E%3Cp%3EThis%20is%20where%20Napper%20breaks%20away%20from%20every%20other%20API%20testing%20tool.%20%3Ca%20href=%22/docs/vs-postman/%22%3EPostman%3C/a%3E%20and%20%3Ca%20href=%22/docs/vs-bruno/%22%3EBruno%3C/a%3E%20give%20you%20a%20sandboxed%20JavaScript%20environment%20with%20limited%20APIs.%20Napper%20lets%20you%20script%20in%20%3Cstrong%3EJavaScript,%20Python,%20F#,%20or%20C#%3C/strong%3E%20%E2%80%94%20whichever%20your%20team%20already%20runs%20%E2%80%94%20on%20the%20real%20runtime,%20with%20full%20access%20to%20npm,%20PyPI,%20and%20NuGet.%20In%20JavaScript%20and%20Python,%20Napper%20injects%20a%20global%20%3Ccode%3Ectx%3C/code%3E%20object%20that%20exposes%20the%20request/response%20and%20lets%20a%20script%20pass%20variables%20to%20later%20steps.%3C/p%3E%3Cp%3EHere&#39;s%20the%20same%20post-request%20hook%20%E2%80%94%20extract%20a%20user%20id,%20chain%20it%20forward,%20validate%20%E2%80%94%20in%20%3Ca%20href=%22/docs/javascript-scripting/%22%3EJavaScript%3C/a%3E%20and%20%3Ca%20href=%22/docs/python-scripting/%22%3EPython%3C/a%3E:%3C/p%3E%3Cpre%20class=%22language-js%22%3E%3Ccode%20class=%22language-js%22%3E%3Cspan%20class=%22token%20comment%22%3E//%20validate-response.js%3C/span%3E%3Cspan%20class=%22token%20comment%22%3E//%20ctx%20is%20injected%20as%20a%20global%20%E2%80%94%20no%20import,%20no%20npm%20install%3C/span%3E%3Cspan%20class=%22token%20keyword%22%3Econst%3C/span%3E%20body%20%3Cspan%20class=%22token%20operator%22%3E=%3C/span%3E%20ctx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Eresponse%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Ejson%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3Ectx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3Eset%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22userId%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E,%3C/span%3E%20%3Cspan%20class=%22token%20function%22%3EString%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3Ebody%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Eid%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3E%3Cspan%20class=%22token%20keyword%22%3Eif%3C/span%3E%20%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3Ebody%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Eid%20%3Cspan%20class=%22token%20operator%22%3E&amp;lt;=%3C/span%3E%20%3Cspan%20class=%22token%20number%22%3E0%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%20ctx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3Efail%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22User%20ID%20must%20be%20positive%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3Ectx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3Elog%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20template-string%22%3E%3Cspan%20class=%22token%20template-punctuation%20string%22%3E%60%3C/span%3E%3Cspan%20class=%22token%20string%22%3ECreated%20user%20%3C/span%3E%3Cspan%20class=%22token%20interpolation%22%3E%3Cspan%20class=%22token%20interpolation-punctuation%20punctuation%22%3E${%3C/span%3Ebody%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Eid%3Cspan%20class=%22token%20interpolation-punctuation%20punctuation%22%3E}%3C/span%3E%3C/span%3E%3Cspan%20class=%22token%20template-punctuation%20string%22%3E%60%3C/span%3E%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3E%3C/code%3E%3C/pre%3E%3Cpre%20class=%22language-python%22%3E%3Ccode%20class=%22language-python%22%3E%3Cspan%20class=%22token%20comment%22%3E#%20validate_response.py%3C/span%3E%3Cspan%20class=%22token%20comment%22%3E#%20ctx%20is%20injected%20as%20a%20global%20%E2%80%94%20no%20import,%20no%20pip%20install%3C/span%3Ebody%20%3Cspan%20class=%22token%20operator%22%3E=%3C/span%3E%20ctx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Eresponse%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Ejsonctx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20builtin%22%3Eset%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22userId%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E,%3C/span%3E%20%3Cspan%20class=%22token%20builtin%22%3Estr%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3Ebody%3Cspan%20class=%22token%20punctuation%22%3E[%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22id%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E]%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20keyword%22%3Eif%3C/span%3E%20body%3Cspan%20class=%22token%20punctuation%22%3E[%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22id%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E]%3C/span%3E%20%3Cspan%20class=%22token%20operator%22%3E&amp;lt;=%3C/span%3E%20%3Cspan%20class=%22token%20number%22%3E0%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20%20%20%20ctx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Efail%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22User%20ID%20must%20be%20positive%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3Ectx%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3Elog%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string-interpolation%22%3E%3Cspan%20class=%22token%20string%22%3Ef%22Created%20user%20%3C/span%3E%3Cspan%20class=%22token%20interpolation%22%3E%3Cspan%20class=%22token%20punctuation%22%3E{%3C/span%3Ebody%3Cspan%20class=%22token%20punctuation%22%3E[%3C/span%3E%3Cspan%20class=%22token%20string%22%3E&#39;id&#39;%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E]%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E}%3C/span%3E%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22%3C/span%3E%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3C/code%3E%3C/pre%3E%3Ch3%20id=%22f-and-c-run-too--on-the-full-net-sdk%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#f-and-c-run-too--on-the-full-net-sdk%22%3EF#%20and%20C#%20run%20too%20%E2%80%94%20on%20the%20full%20.NET%20SDK%3C/a%3E%3C/h3%3E%3Cp%3EPrefer%20.NET?%20F#%20(%3Ccode%3E.fsx%3C/code%3E)%20and%20C#%20(%3Ccode%3E.csx%3C/code%3E)%20scripts%20run%20as%20playlist%20steps%20and%20%3Ccode%3E[script]%3C/code%3E%20pre/post%20hooks%20via%20%3Ccode%3Edotnet%20fsi%3C/code%3E%20and%20%3Ccode%3Edotnet%20script%3C/code%3E,%20with%20the%20entire%20NuGet%20ecosystem.%20Today%20they%20communicate%20through%20stdout%20and%20their%20exit%20code%20%E2%80%94%20the%20injected%20%3Ccode%3Ectx%3C/code%3E%20object%20is%20JavaScript%20and%20Python%20only%20%E2%80%94%20so%20a%20%3Ccode%3E.csx%3C/code%3E%20step%20that%20exits%20non-zero%20fails%20the%20run:%3C/p%3E%3Cpre%20class=%22language-csharp%22%3E%3Ccode%20class=%22language-csharp%22%3E%3Cspan%20class=%22token%20comment%22%3E//%20guard.csx%20%E2%80%94%20a%20playlist%20step%20or%20a%20[script]%20post%20hook%3C/span%3E%3Cspan%20class=%22token%20class-name%22%3E%3Cspan%20class=%22token%20keyword%22%3Evar%3C/span%3E%3C/span%3E%20baseUrl%20%3Cspan%20class=%22token%20operator%22%3E=%3C/span%3E%20Environment%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3EGetEnvironmentVariable%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22API_BASE_URL%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3E%3Cspan%20class=%22token%20keyword%22%3Eif%3C/span%3E%20%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20keyword%22%3Estring%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3EIsNullOrEmpty%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3EbaseUrl%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E{%3C/span%3E%20%20%20%20Console%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3EError%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3EWriteLine%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22API_BASE_URL%20is%20not%20set%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3E%20%20%20%20Environment%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3EExit%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20number%22%3E1%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3E%20%20%20%3Cspan%20class=%22token%20comment%22%3E//%20non-zero%20exit%20-%3E%20the%20step%20fails%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E}%3C/span%3EConsole%3Cspan%20class=%22token%20punctuation%22%3E.%3C/span%3E%3Cspan%20class=%22token%20function%22%3EWriteLine%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E(%3C/span%3E%3Cspan%20class=%22token%20string%22%3E%22[guard]%20environment%20looks%20good%22%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E)%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E;%3C/span%3E%3C/code%3E%3C/pre%3E%3Cp%3EC#%20and%20F#%20scripts%20can%20use%20%3Ccode%3EHttpClient%3C/code%3E,%20%3Ccode%3ESystem.Text.Json%3C/code%3E,%20%3Ccode%3ESystem.Security.Cryptography%3C/code%3E,%20LINQ,%20%3Ccode%3Easync%3C/code%3E/%3Ccode%3Eawait%3C/code%3E%20%E2%80%94%20everything%20.NET%20offers%20%E2%80%94%20and%20any%20%3Ca%20href=%22https://www.nuget.org/%22%3ENuGet%3C/a%3E%20package.%20No%20sandbox.%20The%20runnable%20%3Ca%20href=%22https://github.com/Nimblesite/napper/blob/main/examples/jsonplaceholder/crud-csharp.naplist%22%3E%3Ccode%3Ecrud-csharp.naplist%3C/code%3E%3C/a%3E%20example%20wraps%20the%20CRUD%20requests%20in%20C#%20setup%20and%20teardown%20steps.%3C/p%3E%3Cp%3EYou%20can%20mix%20languages%20in%20the%20same%20project.%20A%20single%20%3Ccode%3E.naplist%3C/code%3E%20can%20reference%20%3Ccode%3E.js%3C/code%3E,%20%3Ccode%3E.py%3C/code%3E,%20%3Ccode%3E.csx%3C/code%3E,%20and%20%3Ccode%3E.fsx%3C/code%3E%20files%20as%20steps.%20Choose%20whichever%20language%20your%20team%20already%20tests%20with%20%E2%80%94%20or%20use%20several.%20See%20the%20%3Ca%20href=%22/docs/scripting/%22%3EScripting%20Overview%3C/a%3E%20for%20the%20full%20picture.%3C/p%3E%3Ch2%20id=%22declarative-assertions--no-scripting-needed-for-the-common-cases%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#declarative-assertions--no-scripting-needed-for-the-common-cases%22%3EDeclarative%20assertions%20%E2%80%94%20no%20scripting%20needed%20for%20the%20common%20cases%3C/a%3E%3C/h2%3E%3Cp%3EMost%20API%20tests%20check%20the%20same%20things:%20status%20codes,%20JSON%20values,%20headers,%20and%20response%20times.%20Napper&#39;s%20%3Ca%20href=%22/docs/assertions/%22%3Eassertion%20syntax%3C/a%3E%20handles%20all%20of%20this%20declaratively%20%E2%80%94%20no%20scripting%20required:%3C/p%3E%3Cpre%3E%3Ccode%3E[assert]status%20=%20200body.id%20=%201body.name%20existsbody.email%20contains%20&amp;quot;@&amp;quot;headers.Content-Type%20contains%20&amp;quot;application/json&amp;quot;duration%20&amp;lt;%20500ms%3C/code%3E%3C/pre%3E%3Cp%3EAll%20assertions%20are%20evaluated%20and%20reported%20individually.%20When%20the%20declarative%20syntax%20isn&#39;t%20enough,%20drop%20into%20%3Ca%20href=%22/docs/javascript-scripting/%22%3EJavaScript%3C/a%3E,%20%3Ca%20href=%22/docs/python-scripting/%22%3EPython%3C/a%3E,%20%3Ca%20href=%22/docs/csharp-scripting/%22%3EC#%3C/a%3E,%20or%20%3Ca%20href=%22/docs/fsharp-scripting/%22%3EF#%3C/a%3E%20for%20complex%20validation%20logic.%3C/p%3E%3Ch2%20id=%22composable-test-suites-with-naplist-files%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#composable-test-suites-with-naplist-files%22%3EComposable%20test%20suites%20with%20.naplist%20files%3C/a%3E%3C/h2%3E%3Cp%3EChain%20requests%20into%20ordered%20test%20suites%20with%20%3Ca%20href=%22/docs/naplist-files/%22%3E.naplist%20files%3C/a%3E.%20Nest%20playlists%20inside%20other%20playlists,%20reference%20entire%20folders,%20and%20mix%20%3Ccode%3E.nap%3C/code%3E%20requests%20with%20%3Ccode%3E.js%3C/code%3E,%20%3Ccode%3E.py%3C/code%3E,%20%3Ccode%3E.csx%3C/code%3E,%20and%20%3Ccode%3E.fsx%3C/code%3E%20scripts:%3C/p%3E%3Cpre%3E%3Ccode%3E[meta]name%20=%20Full%20API%20Suite[steps]./scripts/setup.csx./auth/login.nap./crud-tests.naplist./edge-cases/./scripts/teardown.csx%3C/code%3E%3C/pre%3E%3Ch2%20id=%22built-for-cicd-from-day-one%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#built-for-cicd-from-day-one%22%3EBuilt%20for%20CI/CD%20from%20day%20one%3C/a%3E%3C/h2%3E%3Cp%3ENapper%20is%20designed%20for%20%3Ca%20href=%22/docs/ci-integration/%22%3Econtinuous%20integration%3C/a%3E.%20The%20CLI%20binary%20is%20self-contained%20with%20no%20runtime%20dependencies.%20It%20outputs%20%3Ca%20href=%22https://github.com/testmoapp/junitxml%22%3EJUnit%20XML%3C/a%3E,%20JSON,%20and%20NDJSON%20formats%20natively%20(%3Ccode%3Ecli-output%3C/code%3E).%3C/p%3E%3Ch3%20id=%22github-actions%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#github-actions%22%3EGitHub%20Actions%3C/a%3E%3C/h3%3E%3Cpre%20class=%22language-yaml%22%3E%3Ccode%20class=%22language-yaml%22%3E%3Cspan%20class=%22token%20key%20atrule%22%3Ename%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20API%20Tests%3Cspan%20class=%22token%20key%20atrule%22%3Eon%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20%3Cspan%20class=%22token%20punctuation%22%3E[%3C/span%3Epush%3Cspan%20class=%22token%20punctuation%22%3E,%3C/span%3E%20pull_request%3Cspan%20class=%22token%20punctuation%22%3E]%3C/span%3E%3Cspan%20class=%22token%20key%20atrule%22%3Ejobs%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Etest%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Eruns-on%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20ubuntu%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3Elatest%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Esteps%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20%20%20%20%20%20%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3E%20%3Cspan%20class=%22token%20key%20atrule%22%3Euses%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20actions/checkout@v4%20%20%20%20%20%20%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3E%20%3Cspan%20class=%22token%20key%20atrule%22%3Ename%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20Download%20Napper%20CLI%20%20%20%20%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Erun%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20%3Cspan%20class=%22token%20punctuation%22%3E|%3C/span%3E%3Cspan%20class=%22token%20scalar%20string%22%3E%20%20%20%20%20%20%20%20%20%20curl%20-L%20-o%20napper%20https://github.com/Nimblesite/napper/releases/latest/download/napper-linux-x64%20%20%20%20%20%20%20%20%20%20chmod%20+x%20napper%20%20%20%20%20%20%20%20%20%20sudo%20mv%20napper%20/usr/local/bin/%3C/span%3E%20%20%20%20%20%20%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3E%20%3Cspan%20class=%22token%20key%20atrule%22%3Ename%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20Run%20API%20tests%20%20%20%20%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Erun%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20napper%20run%20./tests/%20%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3Eenv%20ci%20%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3Eoutput%20junit%20%3Cspan%20class=%22token%20punctuation%22%3E%3E%3C/span%3E%20results.xml%20%20%20%20%20%20%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3E%20%3Cspan%20class=%22token%20key%20atrule%22%3Ename%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20Upload%20results%20%20%20%20%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Euses%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20actions/upload%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3Eartifact@v4%20%20%20%20%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Eif%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20always()%20%20%20%20%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Ewith%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Ename%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20api%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3Etest%3Cspan%20class=%22token%20punctuation%22%3E-%3C/span%3Eresults%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22token%20key%20atrule%22%3Epath%3C/span%3E%3Cspan%20class=%22token%20punctuation%22%3E:%3C/span%3E%20results.xml%3C/code%3E%3C/pre%3E%3Cp%3ENapper%20exits%20with%20code%20%3Ccode%3E0%3C/code%3E%20when%20all%20assertions%20pass%20and%20%3Ccode%3E1%3C/code%3E%20when%20any%20assertion%20fails.%20This%20integrates%20natively%20with%20%3Ca%20href=%22https://github.com/features/actions%22%3EGitHub%20Actions%3C/a%3E,%20%3Ca%20href=%22https://docs.gitlab.com/ci/%22%3EGitLab%20CI%3C/a%3E,%20%3Ca%20href=%22https://www.jenkins.io/%22%3EJenkins%3C/a%3E,%20%3Ca%20href=%22https://azure.microsoft.com/en-us/products/devops%22%3EAzure%20DevOps%3C/a%3E,%20and%20any%20CI%20platform%20that%20fails%20on%20non-zero%20exit%20codes.%3C/p%3E%3Ch2%20id=%22migrate-from-http-files-with-one-command%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#migrate-from-http-files-with-one-command%22%3EMigrate%20from%20.http%20files%20with%20one%20command%3C/a%3E%3C/h2%3E%3Cp%3EAlready%20using%20%3Ccode%3E.http%3C/code%3E%20files%20with%20VS%20Code%20REST%20Client%20or%20JetBrains%20IDEs?%20Napper%20includes%20a%20%3Cstrong%3Ebuilt-in%20converter%3C/strong%3E%20that%20transforms%20your%20existing%20%3Ccode%3E.http%3C/code%3E%20files%20into%20%3Ccode%3E.nap%3C/code%3E%20format:%3C/p%3E%3Cpre%20class=%22language-bash%22%3E%3Ccode%20class=%22language-bash%22%3E%3Cspan%20class=%22token%20comment%22%3E#%20Convert%20a%20single%20file%3C/span%3Enapper%20convert%20http%20./requests.http%3Cspan%20class=%22token%20comment%22%3E#%20Convert%20an%20entire%20directory%3C/span%3Enapper%20convert%20http%20./api-tests/%20--output-dir%20./nap-tests/%3C/code%3E%3C/pre%3E%3Cp%3EThe%20converter%20supports%20both%20%3Cstrong%3EMicrosoft%3C/strong%3E%20(VS%20Code%20REST%20Client)%20and%20%3Cstrong%3EJetBrains%3C/strong%3E%20(IntelliJ,%20Rider,%20WebStorm)%20%3Ccode%3E.http%3C/code%3E%20dialects.%20It%20maps%20variables%20to%20%3Ccode%3E.napenv%3C/code%3E%20files,%20preserves%20request%20names,%20converts%20JetBrains%20%3Ccode%3Ehttp-client.env.json%3C/code%3E%20environments,%20and%20warns%20about%20unsupported%20features%20like%20WebSocket%20or%20gRPC%20requests.%3C/p%3E%3Cp%3EMigration%20is%20non-destructive%20%E2%80%94%20your%20original%20%3Ccode%3E.http%3C/code%3E%20files%20are%20untouched.%20Use%20%3Ccode%3E--dry-run%3C/code%3E%20to%20preview%20what%20will%20be%20generated%20before%20writing%20any%20files.%20Once%20converted,%20you%20get%20all%20the%20benefits%20of%20Napper:%20declarative%20assertions,%20composable%20test%20suites,%20scripting%20in%20JavaScript,%20Python,%20F#,%20or%20C#,%20and%20CI/CD%20integration.%3C/p%3E%3Cp%3ESee%20%3Ca%20href=%22/docs/vs-http-files/%22%3ENapper%20vs%20.http%20files%3C/a%3E%20for%20a%20full%20comparison.%3C/p%3E%3Ch2%20id=%22editor-native-lsp-powered%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#editor-native-lsp-powered%22%3EEditor-native,%20LSP-powered%3C/a%3E%3C/h2%3E%3Cp%3ENapper%20meets%20you%20in%20your%20editor.%20There%20are%20first-class%20extensions%20for%20%3Ca%20href=%22https://marketplace.visualstudio.com/items?itemName=nimblesite.napper%22%3EVS%20Code%3C/a%3E%20and%20%3Ca%20href=%22https://zed.dev/%22%3EZed%3C/a%3E%20%E2%80%94%20and%20because%20the%20extension%20is%20published%20to%20the%20%3Ca%20href=%22https://open-vsx.org/extension/nimblesite/napper%22%3EOpen%20VSX%20Registry%3C/a%3E,%20it%20installs%20in%20every%20VS%20Code-compatible%20editor%20too:%20%3Cstrong%3ECursor%3C/strong%3E,%20%3Cstrong%3EWindsurf%3C/strong%3E,%20%3Cstrong%3EAntigravity%3C/strong%3E,%20and%20%3Cstrong%3EVSCodium%3C/strong%3E.%20A%20portable%20%3Cstrong%3Elanguage%20server%3C/strong%3E%20brings%20completions,%20diagnostics,%20and%20hover%20to%20any%20other%20editor%20that%20speaks%20LSP.%20The%20%3Ca%20href=%22https://marketplace.visualstudio.com/items?itemName=nimblesite.napper%22%3ENapper%20VS%20Code%20extension%3C/a%3E%20brings%20the%20full%20experience%20into%20your%20editor:%3C/p%3E%3Cul%3E%3Cli%3E%3Cstrong%3ESyntax%20highlighting%3C/strong%3E%20for%20%3Ccode%3E.nap%3C/code%3E,%20%3Ccode%3E.naplist%3C/code%3E,%20and%20%3Ccode%3E.napenv%3C/code%3E%20files%3C/li%3E%3Cli%3E%3Cstrong%3ERequest%20explorer%3C/strong%3E%20in%20the%20sidebar%20with%20a%20tree%20view%20of%20all%20requests%20and%20playlists%3C/li%3E%3Cli%3E%3Cstrong%3ERun%20requests%3C/strong%3E%20directly%20from%20the%20editor%20with%20a%20single%20click%3C/li%3E%3Cli%3E%3Cstrong%3EEnvironment%20switching%3C/strong%3E%20between%20dev,%20staging,%20production,%20and%20custom%20environments%3C/li%3E%3Cli%3E%3Cstrong%3ETest%20Explorer%20integration%3C/strong%3E%20with%20native%20VS%20Code%20test%20results%3C/li%3E%3Cli%3E%3Cstrong%3EResponse%20inspection%3C/strong%3E%20with%20headers,%20body,%20and%20timing%20information%3C/li%3E%3Cli%3E%3Cstrong%3ECopy%20as%20curl%3C/strong%3E%20to%20share%20requests%20with%20teammates%20who%20don&#39;t%20use%20Napper%3C/li%3E%3C/ul%3E%3Cp%3EThe%20extension%20relies%20on%20the%20CLI%20binary%20to%20run%20requests%20%E2%80%94%20%3Ca%20href=%22/docs/installation/%22%3Einstall%20the%20CLI%3C/a%3E%20first,%20then%20install%20the%20extension%20from%20the%20%3Ca%20href=%22https://marketplace.visualstudio.com/items?itemName=nimblesite.napper%22%3EVS%20Code%20Marketplace%3C/a%3E%20(or%20search%20%3Cstrong%3ENapper%3C/strong%3E%20in%20the%20Extensions%20panel%20of%20Cursor,%20Windsurf,%20or%20Antigravity):%3C/p%3E%3Cpre%20class=%22language-bash%22%3E%3Ccode%20class=%22language-bash%22%3Ecode%20--install-extension%20nimblesite.napper%3C/code%3E%3C/pre%3E%3Ch2%20id=%22how-does-napper-compare%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#how-does-napper-compare%22%3EHow%20does%20Napper%20compare?%3C/a%3E%3C/h2%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%3EFeature%3C/th%3E%3Cth%3ENapper%3C/th%3E%3Cth%3E%3Ca%20href=%22/docs/vs-postman/%22%3EPostman%3C/a%3E%3C/th%3E%3Cth%3E%3Ca%20href=%22/docs/vs-bruno/%22%3EBruno%3C/a%3E%3C/th%3E%3Cth%3E%3Ca%20href=%22/docs/vs-http-files/%22%3E.http%20files%3C/a%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%3ECLI-first%20design%3C/td%3E%3Ctd%3EYes%3C/td%3E%3Ctd%3ENo%3C/td%3E%3Ctd%3EGUI-first%3C/td%3E%3Ctd%3ENo%20CLI%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EEditor%20integration%3C/td%3E%3Ctd%3EVS%20Code,%20Cursor,%20Windsurf,%20Antigravity,%20Zed%20&amp;amp;%20LSP%3C/td%3E%3Ctd%3ESeparate%20app%3C/td%3E%3Ctd%3ESeparate%20app%3C/td%3E%3Ctd%3EREST%20Client%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EGit-friendly%20files%3C/td%3E%3Ctd%3EPlain%20text%3C/td%3E%3Ctd%3EJSON%20blobs%3C/td%3E%3Ctd%3EYes%3C/td%3E%3Ctd%3EYes%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EAssertions%3C/td%3E%3Ctd%3EDeclarative%20+%20scripts%3C/td%3E%3Ctd%3EJS%20scripts%3C/td%3E%3Ctd%3EJS%20scripts%3C/td%3E%3Ctd%3ENone%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EScripting%20language%3C/td%3E%3Ctd%3E%3Cstrong%3EJS,%20Python,%20F#,%20C#%3C/strong%3E%3C/td%3E%3Ctd%3ESandboxed%20JS%3C/td%3E%3Ctd%3ESandboxed%20JS%3C/td%3E%3Ctd%3ENone%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3ECI/CD%20output%3C/td%3E%3Ctd%3EJUnit,%20JSON,%20NDJSON%3C/td%3E%3Ctd%3EVia%20Newman%3C/td%3E%3Ctd%3EVia%20CLI%3C/td%3E%3Ctd%3ENone%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3ETest%20Explorer%3C/td%3E%3Ctd%3ENative%3C/td%3E%3Ctd%3ENo%3C/td%3E%3Ctd%3ENo%3C/td%3E%3Ctd%3ENo%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EOpenAPI%20import%3C/td%3E%3Ctd%3EURL%20+%20file%20+%20AI%3C/td%3E%3Ctd%3EImport%20only%3C/td%3E%3Ctd%3EImport%20only%3C/td%3E%3Ctd%3ENo%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E.http%20file%20migration%3C/td%3E%3Ctd%3EBuilt-in%20converter%3C/td%3E%3Ctd%3EImport%20only%3C/td%3E%3Ctd%3ENo%3C/td%3E%3Ctd%3EN/A%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EAccount%20required%3C/td%3E%3Ctd%3ENo%3C/td%3E%3Ctd%3EYes%3C/td%3E%3Ctd%3ENo%3C/td%3E%3Ctd%3ENo%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EPrice%3C/td%3E%3Ctd%3EFree%20(MIT)%3C/td%3E%3Ctd%3EFreemium%3C/td%3E%3Ctd%3EFree%20(MIT)%3C/td%3E%3Ctd%3EFree%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch2%20id=%22get-started-in-5-minutes%22%20tabindex=%22-1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#get-started-in-5-minutes%22%3EGet%20started%20in%205%20minutes%3C/a%3E%3C/h2%3E%3Col%3E%3Cli%3E%3Ca%20href=%22/docs/installation/%22%3EInstall%20the%20CLI%20or%20VS%20Code%20extension%3C/a%3E%3C/li%3E%3Cli%3EFollow%20the%20%3Ca%20href=%22/docs/quick-start/%22%3EQuick%20Start%20guide%3C/a%3E%20to%20create%20your%20first%20request%3C/li%3E%3Cli%3E%3Ca%20href=%22/docs/vs-http-files/%22%3EMigrate%20existing%20.http%20files%3C/a%3E%20with%20%3Ccode%3Enapper%20convert%20http%3C/code%3E%3C/li%3E%3Cli%3EAdd%20%3Ca%20href=%22/docs/assertions/%22%3Eassertions%3C/a%3E%20to%20validate%20responses%3C/li%3E%3Cli%3ESet%20up%20%3Ca%20href=%22/docs/environments/%22%3Eenvironments%3C/a%3E%20for%20different%20targets%3C/li%3E%3Cli%3EWrite%20scripts%20in%20%3Ca%20href=%22/docs/javascript-scripting/%22%3EJavaScript%3C/a%3E,%20%3Ca%20href=%22/docs/python-scripting/%22%3EPython%3C/a%3E,%20%3Ca%20href=%22/docs/csharp-scripting/%22%3EC#%3C/a%3E,%20or%20%3Ca%20href=%22/docs/fsharp-scripting/%22%3EF#%3C/a%3E%20for%20advanced%20flows%3C/li%3E%3Cli%3ERun%20everything%20in%20%3Ca%20href=%22/docs/ci-integration/%22%3ECI/CD%3C/a%3E%20with%20JUnit%20XML%20output%3C/li%3E%3C/ol%3E%3Cp%3ENapper%20is%20free,%20open%20source,%20and%20%3Ca%20href=%22https://github.com/Nimblesite/napper/blob/main/LICENSE%22%3EMIT%20licensed%3C/a%3E.%20Browse%20the%20source%20code%20and%20examples%20on%20%3Ca%20href=%22https://github.com/Nimblesite/napper%22%3EGitHub%3C/a%3E.%3C/p%3E</content>
    <summary>Introducing Napper, a free, open-source, CLI-first API testing tool for VS Code, Zed, and any editor. A modern alternative to Postman, Bruno, and .http files with scripting in JavaScript, Python, F#, or C#, declarative assertions, composable test suites, built-in .http file conversion, and CI/CD integration via JUnit XML.</summary>
  </entry>
</feed>
