1"use strict";(globalThis.webpackChunkdocs||=[]).push([[3947],{86032(e,t,a){a.r(t),a.d(t,{assets:()=>d,contentTitle:()=>c,default:()=>p,frontMatter:()=>l,metadata:()=>i,toc:()=>u});var n=a.cw((function(e,t){const n=a.p+"assets/images/ff-service-9bfd5d029bfcd0ebbea6c6cab79b6a14.png";a.d(t,["A",0,n])}));const i=JSON.parse('{"id":"reference/intro","title":"Introduction","description":"OpenFeature is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool.","source":"@site/docs/reference/intro.mdx","sourceDirName":"reference","slug":"/reference/intro","permalink":"/docs/reference/intro","draft":false,"unlisted":false,"editUrl":"https://github.com/open-feature/openfeature.dev/edit/main/docs/reference/intro.mdx","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"sidebar_position":1,"id":"intro","title":"Introduction"},"sidebar":"docs","next":{"title":"Concepts","permalink":"/docs/category/concepts"}}');var r=a(74848),o=a(28453),s=a(77833);const l={sidebar_position:1,id:"intro",title:"Introduction"},c="Welcome to OpenFeature",d={},u=[{value:"What are feature flags?",id:"what-are-feature-flags",level:2},{value:"What is OpenFeature?",id:"what-is-openfeature",level:2},{value:"Evaluation API",id:"evaluation-api",level:3},{value:"Evaluation Context",id:"evaluation-context",level:3},{value:"Providers",id:"providers",level:3},{value:"Hooks",id:"hooks",level:3},{value:"Events",id:"events",level:3}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"welcome-to-openfeature",children:"Welcome to OpenFeature"})}),"\n",(0,r.jsx)(t.p,{children:"OpenFeature is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool."}),"\n",(0,r.jsx)(t.h2,{id:"what-are-feature-flags",children:"What are feature flags?"}),"\n",(0,r.jsx)(t.p,{children:"In the most basic case, you can think of a feature flag as an if/else statement that can be controlled at runtime.\nFeature flags allow application behavior to be altered without the deployment of new code."}),"\n",(0,r.jsx)(t.p,{children:"This capability serves a variety of purposes.\nYou can reduce the need for long-running feature branches.\nYou can hide work-in-progress functionality from end users, while still exposing it for internal testing.\nYou can perform canary releases - rolling out a new feature to an initially small subset of users.\nYou can perform A/B testing.\nYou can safely degrade parts of a production system that are experiencing an outage.\nYou can restrict access to specific product functionality based on user-characteristics such as geography or IP address, for usability, compliance or licensing reasons."}),"\n",(0,r.jsxs)(t.p,{children:["Feature flags are ",(0,r.jsx)(t.em,{children:"dynamic"}),"; they are evaluated at runtime.\nMany of the use cases just described also require feature flags to be ",(0,r.jsx)(t.em,{children:"context-aware"})," - a flagging decision must take into account things like which user is making a web request.\nWhat's more, the configuration behind flagging decisions also needs to be dynamic to support use cases like canary releases where you gradually roll a feature out to more users without having to redeploy or restart anything."]}),"\n",(0,r.jsx)(t.p,{children:"Given all these requirements (along with others such as an admin UI, audit trails, environment management, and more) it's clear that full use of feature flags requires a feature flagging system - typically a stand-alone feature-flagging service along with a client library which interacts with that service."}),"\n",(0,r.jsxs)("figure",{children:[(0,r.jsx)("img",{src:n().A}),(0,r.jsx)("figcaption",{children:(0,r.jsx)("i",{children:"A typical feature-flagging system"})})]}),"\n",(0,r.jsx)(t.h2,{id:"what-is-openfeature",children:"What is OpenFeature?"}),"\n",(0,r.jsxs)(t.p,{children:["OpenFeature provides a shared, standardized feature flagging client - an ",(0,r.jsx)(t.em,{children:"SDK"})," - which can be plugged into various 3rd-party feature flagging ",(0,r.jsx)(t.em,{children:"providers"}),".\nWhether you're using an open-source system or a commercial product, whether it's self-hosted or cloud-hosted, OpenFeature provides a consistent, unified API for developers to use feature flagging in their applications."]}),"\n",(0,r.jsxs)("figure",{children:[(0,r.jsx)("img",{src:a(52363).A}),(0,r.jsx)("figcaption",{children:(0,r.jsx)("i",{children:'OpenFeature integrated
1with a hypothetical "Flags-R-us" flag management system'})})]}),"\n",(0,r.jsx)(t.p,{children:"To accomplish this, the OpenFeature SDK defines a number of flexible abstractions."}),"\n","\n",(0,r.jsx)("div",{className:"video-container",children:(0,r.jsx)(s.A,{id:"heQ83k15ZE4",title:"YouTube video player",poster:"maxresdefault",webp:!0})}),"\n",(0,r.jsx)(t.h3,{id:"evaluation-api",children:"Evaluation API"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/docs/reference/concepts/evaluation-api",children:"evaluation API"})," is the part of the OpenFeature SDK that an ",(0,r.jsx)(t.em,{children:"application author"})," interacts with.\nIt allows developers to evaluate feature flags, and use the resulting values to impact control flow or application characteristics.\nThe evaluation API provides a framework that allows for customization of behavior and integration with various tools."]}),"\n",(0,r.jsx)(t.h3,{id:"evaluation-context",children:"Evaluation Context"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/docs/reference/concepts/evaluation-context",children:"evaluation context"})," is a container for arbitrary contextual data that can be used as a basis for dynamic evaluation.\nStatic data such as the host or an identifier for the application can be configured globally.\nDynamic evaluation context, such as the IP address of the client in a web application, can be implicitly propagated or explicitly passed during flag evaluation, and can be merged with static values."]}),"\n",(0,r.jsx)(t.h3,{id:"providers",children:"Providers"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"/docs/reference/concepts/provider",children:"Providers"}),' are the "translation layer" between the evaluation API and the flag management system in use.\nProviders are responsible for mapping the arguments supplied to the evaluation API to their equivalent representation in the associated flag management system.\nProviders might wrap a vendor SDK, call a bespoke flag evaluation REST API, or even parse some locally stored file to resolve flag values.']}),"\n",(0,r.jsx)(t.h3,{id:"hooks",children:"Hooks"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"/docs/reference/concepts/hooks",children:"Hooks"})," are a mechanism that allow for the addition of arbitrary behavior at various points in the ",(0,r.jsx)(t.em,{children:"flag evaluation life-cycle"}),".\nHooks let you extend the OpenFeature SDK, adding functionality such as validating a resolved flag value, modifying or adding data to the evaluation context, logging, telemetry, and tracking."]}),"\n",(0,r.jsx)(t.h3,{id:"events",children:"Events"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"/docs/reference/concepts/events",children:"Events"})," enable the ability to react to state changes in the provider or underlying flag management system.\nThese include changes in provider readiness, error status, or perhaps most interestingly, flag configuration changes."]})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},52363(e,t,a){const n=a.p+"assets/images/of-architecture-a49b167df4037d936bd6623907d84de1.png";a.d(t,["A",0,n])},28453(e,t,a){a.d(t,{R:()=>o,x:()=>s});var n=a(96540);const i={},r=n.createContext(i);function o(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(r.Provider,{value:t},e.children)}},77833(e,t,a){var n=a(74848),i=a(96540);const r={default:120,mqdefault:320,hqdefault:480,sddefault:640,maxresdefault:1280};function o(e,t,a,n,i){const r={"@context":"https://schema.org","@type":"VideoObject",name:(null==i?void 0:i.name)||t,thumbnailUrl:[(null==i?void 0:i.thumbnailUrl)||a],embedUrl:(null==i?void 0:i.embedUrl)||`${n}/embed/${e}`,contentUrl:(null==i?void 0:i.contentUrl)||`https://www.youtube.com/watch?v=${e}`,...(null==i?void 0:i.description)&&{description:i.description},...(null==i?void 0:i.uploadDate)&&{uploadDate:i.uploadDate},...(null==i?void 0:i.duration)&&{duration:i.duration}};return JSON.stringify(r)}const s=i.forwardRef((function(e,t){const[a,s]=i.useState(!1),[l,c]=i.useState(e.alwaysLoadIframe||!1),d=encodeURIComponent(e.id),u="string"==typeof e.playlistCoverId?encodeURIComponent(e.playlistCoverId):null,h=e.title,p=e.poster||"hqdefault",f=e.announce||"Watch",m=!e.alwaysLoadIframe||e.autoplay&&e.muted,g=i.useMemo((()=>{const t=new URLSearchParams({...e.muted?{mute:"1"}:{},...m?{autoplay:"1"}:{},...e.enableJsApi?{enablejsapi:"1"}:{},...e.playlist?{list:d}:{}});return e.params&&new URLSearchParams(e.params.startsWith("&")?e.params.slice(1):e.params).forEac
1h(((e,a)=>{t.append(a,e)})),t}),[e.muted,m,e.enableJsApi,e.playlist,d,e.params]),v=i.useMemo((()=>e.cookie?"https://www.youtube.com":"https://www.youtube-nocookie.com"),[e.cookie]),y=i.useMemo((()=>e.playlist?`${v}/embed/videoseries?${g.toString()}`:`${v}/embed/${d}?${g.toString()}`),[e.playlist,v,d,g]),b=!e.thumbnail&&!e.playlist&&"maxresdefault"===p,x=e.webp?"webp":"jpg",w=e.webp?"vi_webp":"vi",j=b?((e,t,a,n="maxresdefault")=>{const[o,s]=(0,i.useState)("");return(0,i.useEffect)((()=>{const i=`https://img.youtube.com/${t}/${e}/${n}.${a}`,o=`https://img.youtube.com/${t}/${e}/hqdefault.${a}`,l=r[n],c=new Image;c.onload=()=>{c.width<l?s(o):s(i)},c.onerror=()=>s(o),c.src=i}),[e,t,a,n]),o})(e.id,w,x,p):null,k=i.useMemo((()=>e.thumbnail||j||`https://i.ytimg.com/${w}/${e.playlist?u:d}/${p}.${x}`),[e.thumbnail,j,w,e.playlist,u,d,p,x]),I=e.activatedClass||"lyt-activated",$=e.adNetwork||!1,P=e.aspectHeight||9,A=e.aspectWidth||16,F=e.iframeClass||"",O=e.playerClass||"lty-playbtn",S=e.wrapperClass||"yt-lite",C=i.useCallback(e.onIframeAdded||function(){},[e.onIframeAdded]),T=e.rel?"prefetch":"preload",E=e.containerElement||"article",W=!1!==e.noscriptFallback;return i.useEffect((()=>{l&&(C(),e.focusOnLoad&&"object"==typeof t&&null!=t&&t.current&&t.current.focus())}),[l,C,e.focusOnLoad,t]),(0,n.jsxs)(n.Fragment,{children:[!e.lazyLoad&&(0,n.jsx)("link",{rel:T,href:k,as:"image"}),(0,n.jsx)(n.Fragment,{children:a&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("link",{rel:"preconnect",href:v}),(0,n.jsx)("link",{rel:"preconnect",href:"https://www.google.com"}),$&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("link",{rel:"preconnect",href:"https://static.doubleclick.net"}),(0,n.jsx)("link",{rel:"preconnect",href:"https://googleads.g.doubleclick.net"})]})]})}),e.seo&&!e.playlist&&(0,n.jsx)("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:o(e.id,h,k,v,e.seo)}}),W&&!e.playlist&&(0,n.jsx)("noscript",{children:(0,n.jsxs)("a",{href:`https://www.youtube.com/watch?v=${e.id}`,"aria-label":`Watch ${h} on YouTube`,children:['Watch "',h,'" on YouTube']})}),(0,n.jsxs)(E,{onPointerOver:()=>{a||s(!0)},onClick:()=>{l||c(!0)},className:`${S} ${l?I:""}`,"data-title":h,role:l?void 0:"img","aria-label":l?void 0:`${h} - YouTube video preview`,style:{...!e.lazyLoad&&{backgroundImage:`url(${k})`},"--aspect-ratio":P/A*100+"%",...e.style||{}},children:[e.lazyLoad&&!l&&(0,n.jsx)("img",{src:k,alt:`${h} - YouTube thumbnail`,className:"lty-thumbnail",loading:"lazy"}),(0,n.jsx)("button",{type:"button",className:O,"aria-label":`${f} ${h}`,"aria-hidden":l||void 0,tabIndex:l?-1:0,children:(0,n.jsx)("span",{className:"lty-visually-hidden",children:f})}),l&&(0,n.jsx)("iframe",{ref:t,className:F,title:h,width:"560",height:"315",style:{border:0},allow:"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0,src:y,referrerPolicy:e.referrerPolicy||"strict-origin-when-cross-origin"})]})]})}));a.d(t,["A",0,s])}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.