{"id":20441383,"url":"https://github.com/sandromaglione/effect-getting-started","last_synced_at":"2025-06-26T07:01:56.230Z","repository":{"id":206799263,"uuid":"716899839","full_name":"SandroMaglione/effect-getting-started","owner":"SandroMaglione","description":"Example apps to get started using all the features of effect: Context, Layer, Runtime, Scope and more 🪄","archived":false,"fork":false,"pushed_at":"2024-06-11T17:00:42.000Z","size":161,"stargazers_count":42,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-12T23:25:59.604Z","etag":null,"topics":["effect","effect-ts","functional-programming"],"latest_commit_sha":null,"homepage":"https://www.sandromaglione.com/newsletter","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SandroMaglione.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-10T05:28:58.000Z","updated_at":"2025-04-11T06:02:43.000Z","dependencies_parsed_at":"2024-06-11T20:14:44.406Z","dependency_job_id":"ef82503d-af07-4f2a-bc66-4807628af538","html_url":"https://github.com/SandroMaglione/effect-getting-started","commit_stats":{"total_commits":20,"total_committers":1,"mean_commits":20.0,"dds":0.0,"last_synced_commit":"72913696fc0e9dc8d88f1f0cae8fe451ccc9ed1e"},"previous_names":["sandromaglione/effect-getting-started"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SandroMaglione/effect-getting-started","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SandroMaglione%2Feffect-getting-started","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SandroMaglione%2Feffect-getting-started/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SandroMaglione%2Feffect-getting-started/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SandroMaglione%2Feffect-getting-started/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SandroMaglione","download_url":"https://codeload.github.com/SandroMaglione/effect-getting-started/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SandroMaglione%2Feffect-getting-started/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262018662,"owners_count":23245615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["effect","effect-ts","functional-programming"],"created_at":"2024-11-15T09:32:32.982Z","updated_at":"2025-06-26T07:01:56.212Z","avatar_url":"https://github.com/SandroMaglione.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# How to `effect`\n\u003cp\u003e\n  \u003ca href=\"https://github.com/SandroMaglione\"\u003e\n    \u003cimg alt=\"GitHub: SandroMaglione\" src=\"https://img.shields.io/github/followers/SandroMaglione?label=Follow\u0026style=social\" target=\"_blank\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://twitter.com/SandroMaglione\"\u003e\n    \u003cimg alt=\"Twitter: SandroMaglione\" src=\"https://img.shields.io/twitter/follow/SandroMaglione.svg?style=social\" target=\"_blank\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n***\n\nThis project is part of my weekly newsletter at [**sandromaglione.com**](https://www.sandromaglione.com/newsletter?ref=Github\u0026utm_medium=newsletter_project\u0026utm_term=xstate\u0026utm_term=effect).\n\n\n\u003ca href=\"https://www.sandromaglione.com/newsletter?ref=Github\u0026utm_medium=newsletter_project\u0026utm_term=effect\"\u003e\n    \u003cimg alt=\"sandromaglione.com Newsletter weekly project\" src=\"https://www.sandromaglione.com/static/images/newsletter_banner.webp\" target=\"_blank\" /\u003e \n\u003c/a\u003e\n\n## Project structure\nThis is a collection of examples of how to use [`effect`](https://github.com/Effect-TS/effect).\n\nThis is a **deep** dive exploration of the features and *internals* offered by `effect`.\n\n## How to use\nInstall:\n\n```bash\npnpm install\n```\n\nThen you can run each script (take a look at `package.json` for the list of all the scripts you can run):\n\n```bash\npnpm run index\n```\n\n\u003e **Note**: The convention is that files that start with a lowercase letter are runnable scripts\n\nTake a look also at [`test`](/test/).\n\n***\n\n## Notes\n\n### Base64\nNo need to install extra libraries like `js-base64`. The `Encoding` module provides encoding/decoding of base64.\n\n### `Context` (`Tag`)\nInside [`GlobalValue`](https://github.com/Effect-TS/effect/blob/main/packages/effect/src/GlobalValue.ts#L17) Effect stores a `globalStore` of type `Map\u003cunknown, any\u003e`.\n\nInside this store the `Context` module registers a [`tagRegistry`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L59):\n\n```ts\nconst tagRegistry = globalValue(\"effect/Context/Tag/tagRegistry\", () =\u003e new Map\u003cany, C.Tag\u003cany, any\u003e\u003e())\n```\n\nInside this registry Effect collects all `Tag`s, created using `Context.Tag` by calling the *internal* [`makeTag`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L62).\n\n\u003e [!Note]\n\u003e When you pass an `identifier` to `Context.Tag` you specify a key for the `tagRegistry`. Effect [checks the registry](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L63-L65) when accessing and creating a new tag.\n\nA `Tag` is an instance of [`Pipeable`](https://github.com/Effect-TS/effect/blob/main/packages/effect/src/Pipeable.ts#L9). This allows to chain `.pipe` to an instance of `Tag` to extract the methods of a service:\n\n```ts\ninterface Base64Service {\n  readonly decode: (\n    source: string\n  ) =\u003e Effect.Effect\u003cnever, Base64DecodeError, string\u003e;\n}\n\nexport const Base64Service = Context.Tag\u003cBase64Service\u003e(\"@app/Base64Service\");\n\n/** Use `pipe` to extract the methods from the service 👆 */\nconst result = Base64.Base64Service.pipe(\n  Effect.flatMap((base64) =\u003e base64.decode(\"Zm9vYmFy\")),\n  Effect.provide(Base64.Base64ServiceLive), // 👈 Then provide a valid instance\n  Effect.runSync\n);\n```\n\n`Tag` (`Context`) is also a valid [instance of `Effect`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/Effect.ts#L150-L157). This allows to use methods such as `flatMap`.\n\n### `ContextProto`\nAn instance of `Context` is created by copying a [context prototype](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L87-L122) (using [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) inside the *internal* [`makeContext`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/context.ts#L125-L129))\n\n### `Iterable`\nThe [Iteration protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) define an `Iterable` interface:\n\n```ts\ninterface Iterator\u003cT, TReturn = any, TNext = undefined\u003e {\n  next(...args: [] | [TNext]): IteratorResult\u003cT, TReturn\u003e;\n  return?(value?: TReturn): IteratorResult\u003cT, TReturn\u003e;\n  throw?(e?: any): IteratorResult\u003cT, TReturn\u003e;\n}\n\ninterface Iterable\u003cT\u003e {\n  [Symbol.iterator](): Iterator\u003cT\u003e;\n}\n```\n\nThe `Effect` type [defines an iterator](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/Effect.ts#L1123). This allows to use `yield*` in `Effect.gen` ([`EffectGen`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/core-effect.ts#L778-L784) and [`SingleShotGen`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/Utils.ts#L102-L146)).\n\nThis is also used by Effect to define methods such as [`map`](https://github.com/Effect-TS/effect/blob/14e4393ebe3ba2635c73297bf7cd6750c883e669/packages/effect/src/internal/Iterable.ts#L43-L54).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandromaglione%2Feffect-getting-started","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsandromaglione%2Feffect-getting-started","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandromaglione%2Feffect-getting-started/lists"}