{"id":28521460,"url":"https://github.com/cozy/cozy-guidelines","last_synced_at":"2025-09-15T09:06:34.705Z","repository":{"id":12178037,"uuid":"14777903","full_name":"cozy/cozy-guidelines","owner":"cozy","description":"Cozy Code Guidelines","archived":false,"fork":false,"pushed_at":"2024-05-22T08:54:24.000Z","size":168,"stargazers_count":12,"open_issues_count":1,"forks_count":12,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-07-03T17:47:38.572Z","etag":null,"topics":["coding-guidelines","cozy"],"latest_commit_sha":null,"homepage":"https://cozy.github.io/cozy-guidelines/","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cozy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-11-28T13:42:14.000Z","updated_at":"2024-12-27T03:45:28.000Z","dependencies_parsed_at":"2024-05-22T10:03:19.597Z","dependency_job_id":null,"html_url":"https://github.com/cozy/cozy-guidelines","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cozy/cozy-guidelines","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozy%2Fcozy-guidelines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozy%2Fcozy-guidelines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozy%2Fcozy-guidelines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozy%2Fcozy-guidelines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cozy","download_url":"https://codeload.github.com/cozy/cozy-guidelines/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozy%2Fcozy-guidelines/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275232740,"owners_count":25428230,"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","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["coding-guidelines","cozy"],"created_at":"2025-06-09T07:36:21.618Z","updated_at":"2025-09-15T09:06:34.654Z","avatar_url":"https://github.com/cozy.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cozy Code Guidelines\n\n- [Cozy Code Guidelines](#cozy-code-guidelines)\n- [Naming of Functions](#naming-of-functions)\n- [Naming of Queries](#naming-of-queries)\n- [Import order](#import-order)\n- [JavaScript](#javascript)\n  - [Return value](#return-value)\n  - [Promises vs async/await](#promises-vs-asyncawait)\n  - [Comments](#comments)\n  - [Date](#date)\n    - [JavaScript Internationalization API](#javascript-internationalization-api)\n    - [Date-fns](#date-fns)\n  - [Redirections](#redirections)\n- [React](#react)\n  - [Generic code style](#generic-code-style)\n  - [Prefer Functional Components](#prefer-functional-components)\n  - [React Memo](#react-memo)\n    - [Could I use Memoization?](#could-i-use-memoization)\n    - [Examples when to use memoization](#examples-when-to-use-memoization)\n      - [Live example](#live-example)\n      - [Theoretical examples](#theoretical-examples)\n  - [Styling / theming](#styling--theming)\n  - [Test libraries and tools](#test-libraries-and-tools)\n- [Tests](#tests)\n  - [Unit test files](#unit-test-files)\n  - [Data Test Id](#data-test-id)\n- [Dependencies](#dependencies)\n- [Unit Commit](#unit-commit)\n- [Commit messages](#commit-messages)\n    - [Type](#type)\n    - [Scope (optional)](#scope-optional)\n    - [Subject](#subject)\n    - [Body aka commit description (optional but recommended)](#body-aka-commit-description-optional-but-recommended)\n    - [Footer](#footer)\n    - [Breaking change](#breaking-change)\n        - [Example](#example)\n- [Pull requests](#pull-requests)\n- [Travis](#travis)\n  - [Deploy](#deploy)\n- [Secrets](#secrets)\n  - [Encrypted variables](#encrypted-variables)\n    - [Travis](#travis-1)\n  - [Secrets File](#secrets-file)\n- [Feature flags](#feature-flags)\n- [Release process](#release-process)\n- [Cozy Logo](#cozy-logo)\n  - [What is Cozy?](#what-is-cozy)\n  - [Community](#community)\n\n\n# Naming of Functions\n\nTo name functions, you can use some keywords that everyone will understand, like those ones :\n\n`fetchSomething` : should access data by making a server side call\n\n`getSomething` : should access data without making a server side call\n\n`findSomething` : like the get, but with arguments\n\n`normalizeSomething` : should transform data to conform to a given schema or to make sure that is coherent with other documents\n\n`saveSomething` : creates or updates a document\n\n`hasSomething` or `isSomething` : should describe a boolean variable\n\n`computeSomething` : create something from other elements\n\n`makeSomething` : create something from scratch\n\n`doSomethingAndForget` : to convert an async func `doSomething` to a sync one `doSomethingAndForget`\n\n`ensureSomething` : make sure something {is/has been} done\n\n# Naming of Queries\n\nBy \"naming queries\" we mean defining the `as` attribute of the queries options usable in cozy-client:\n\n```\nconst queryResult = useQuery(Q(DOCTYPE), {\n    as: ...,\n    fetchPolicy: ...\n  })\n```\n\nBy default `as` must be defined according to the doctype used: `as: DOCTYPE`\n\nIf the query can be built with parameters (in this case `id`, `account` and `date`), these parameters must be included after `id` by preceding them with a `/[PARAM_NAME]/` (note that this is unnecessary for `id`):\n\n```\nas: `${DOCTYPE}/${id}/account/${account}/date/${date}`\n```\n\n# Import order\n```js\nimport libs from externals // (ex: lodash)\n\nimport libs from internal // (ex: cozy-client)\n\nimport libs from local // (absolute or relative path, depending on the project)\nimport styles from local // (absolute or relative path, depending on the project)\n```\n\n# JavaScript\n\n## Return value\n\nAvoid using `undefined` and prefer returning `null`.\n\n\u003e Why ? `undefined` is used for variable that have not been assigned yet. `null` is for a variable with no value.\n\u003e See http://www.ecma-international.org/ecma-262/6.0/#sec-undefined-value, http://www.ecma-international.org/ecma-262/6.0/#sec-null-value\n\n## Promises vs async/await\n\nAlways use async / await when applicable, instead of Promises and `then()` chains.\n\n\u003e Why ? Cleaner, Clearer, more readable, easier for handling errors\n\u003e See https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9\n\n## Comments\n\nOnly comments things that have business logic complexity.\n\n\u003e Why ? Comments are an apology, not a requirement. Good code _mostly_ documents itself.\n\u003e See https://github.com/ryanmcdermott/clean-code-javascript#comments\n\n❌ Bad :\n\n```\n// Initiate API UserData object, for checkFormLogin token\nconst req1 = await request({\n  url: `https://www.deezer.com/ajax/gw-light.php?method=deezer.getUserData\u0026input=3\u0026api_version=1.0\u0026api_token=\u0026cid=`\n})\n```\n\n✅ Good\n\n```\nfunction initiateAPIForToken () {\n  return request({\n    url: `https://www.deezer.com/ajax/gw-light.php?method=deezer.getUserData\u0026input=3\u0026api_version=1.0\u0026api_token=\u0026cid=`\n  })\n}\n```\n\n## Date\n\nDate management dependencies may increase app bundle and are not always useful.\n\nIn order to uniform our usage of date management package, we discourage any use of `moment`\nThe main reason is that project was built for the previous era of the JavaScript ecosystem and since September 2020, for [more details](https://momentjs.com/docs/#/-project-status/)\n\n[Looking for alternatives](https://blog.logrocket.com/4-alternatives-to-moment-js-for-internationalizing-dates/), we use in that order:\n\n### [JavaScript Internationalization API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)\nBecause nothing beats using native features:\n\nEspecially\n- Intl.DateTimeFormat, which provides date and time formatting\n- Intl.RelativeTimeFormat, which provides language-sensitive easy-to-read phrases for dates and timestamps\n\n### [Date-fns](https://date-fns.org/)\n[Date-fns]((https://github.com/cozy/cozy-ui/blob/master/react/I18n/format.jsx#L1)) can be used directly inside our app.\n\n`const { f } = useI18n()`\n\nThe whole configuration can be found inside [Cozy-UI/I18n folder](https://github.com/cozy/cozy-ui/blob/master/react/I18n)\n\n## Redirections\n\nIf you need to make a link between cozy's apps, you should always use AppLinker from Cozy-UI. It handles a lot of use cases (flagship app, mobile app...).\nNever rely on `window.location` in the cozy-apps' codebase. We do a few things that can have repercussion on this value. Always use the generateWebLink method. To use it, you'll have to get the subdomainType. And to get the subdomainType, you'll need to read it from the client: `const { subdomain: subDomainType } = client.getInstanceOptions()`\n\n# React\n\n## Generic code style\n\n```\n\"eslintConfig\": {\n    \"extends\": [\"eslint-config-cozy-app\"]\n  }\n```\n\nLet the formatters do their jobs.\n\n## Prefer Functional Components\n\nFor any new component in our codebase, we prefer using [functional component](https://github.com/tatethurston/eslint-plugin-react-prefer-function-component#motivation=)\n\n## Prefer export over export default\n\nFor exporting new component in our codebase, we prefet using `export { ComponentName }` over `export default ComponentName`. This makes maintenance easier by making renaming more explicit when importing.\n\n## React Memo\n\nUsage of React.memo / useMemo / useCallback is quite tricky. We recommend to [use React.memo wisely](https://dmitripavlutin.com/use-react-memo-wisely/).\nWe use React.memo only for **medium/big** component that renders **often** with the **same props**.\n\n![img](https://dmitripavlutin.com/static/c07d2ce4ede6301197b9605a75ae9b4e/5fd6b/when-to-use-react-memo-infographic.jpg)\n\n\u003e Don't use memoization if you can't quantify the performance gains.\n\nStrictly, React uses memoization as a performance hint.\nWhile in most situations React avoids rendering a memoized component, you shouldn't count on that to prevent rendering.\n\n### Could I use Memoization?\n\nUse the [React profiler](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) or [a profiling extension](https://reactjs.org/docs/optimizing-performance.html#profiling-components-with-the-devtools-profiler) to measure the benefits of applying React.memo().\n\n### Examples when to use memoization\n\n#### Live example\nIn this [example](https://prateeksurana.me/blog/when-should-you-memoize-in-react/#memo), we have an example of (not so big) component rendering a lot (because of realtime values provided by usePokemon hook).\n\n#### Theoretical examples\nIn Cozy application, we may consider using memoization inside:\n- Page / Views are big components, rendering a lot if they depend on props.\n- slow calls to API (that lasts more than 200ms) that are not cached / using pouchdb\n- big operations (ex: increment to 10 000)\n\n## Event handling\n\nPrefer named function instead of inline function into event handler.\n\nWith Typescript, if you have trouble with eslint rule `no-misused-promises` because your function is returning an `Promise\u003cvoid\u003e`. You can disable this rule for your specific case\n\n## Styling / theming\n\n- Use components from cozy-ui when possible\n- When coding a component, try to avoid stylus and prefer material UI's default solutions for theming (withStyles)\n\nSee also [cozy-ui guidelines on component development](https://github.com/cozy/cozy-ui/tree/master/docs#guidelines-for-component-development).\n\n## Test libraries and tools\n\n- enzyme is deprecated. We use testing-library/react instead. It is always good to refactor an enzyme compliant test to a testing-library/react compliant test.\n- testcafe is deprecated.\n- We do not use snapshots anymore. Do not add new snapshots.\n\n# Tests\n\n## Unit test files\n\nUnit test files should be located next to their source file, rather then in a subfolder (for example `__tests__`). This keeps them closer to their source file and encourages their maintenance.\n\n:+1: Cool\n\n```\nsrc\n├── greetings\n│   └── components\n│        └── Greeting.jsx\n│        └── Greeting.spec.js\n```\n\n❌ Bad\n\n```\nsrc\n├── greetings\n│   └── components\n│        └── Greeting.jsx\ntest\n├── greetings\n│   └── components\n│        └── Greeting.spec.js\n```\n\n## Data Test Id\n\nIn order to uniform `data-testid`, we decided to use only `data-testid`. It helps coherency when testing with Testing Library\n\n:+1: Cool\n\n```\n\u003cdiv\n  data-testid=\"id-of-div-to-test\"\n/\u003e\n```\n\n❌  Bad :\n\n```\n\n\u003cdiv\n  data-test-id=\"incorrect-way-to-use-data-testid\"\n/\u003e\n```\n\n## queryBy ⚡️ toBeDefined\n`queryBy*` methods return an array of Element(s) or `null` and `.toBeDefined()` fail only if value is `undefined`\n\n:+1: Cool\n```\nexpect(queryByTestId('foo')).toBeInDocument()\nexpect(queryByTestId('foo')).toBe(null)\n```\n❌  Bad :\n```\nexpect(queryByTestId('foo')).toBeDefined()\n```\nSee: https://testing-library.com/docs/queries/about/#types-of-queries\n\n# Dependencies\n\n\u003e 👉 Avoid directly calling Material-UI in Cozy Library and Cozy Application\n\nApart from Cozy-UI, repository should prevent from requiring material-ui as dependency.\n\n\u003e 👉 Inside Cozy library, any package except cozy-* or react or react-dom can be a dependency\n\nIt's complicated to be sure that the application calling a cozy-library has any other dependency.\nThat's why it's recommended to use dependency (when called in the production code)\n\nExample:\n- react-router-dom should be a dependency\n- eslint should be a devDependencies\n- cozy-ui should be a devDependencies and a peerDependencies\n\n\n\u003cdetails\u003e\n    \u003csummary\u003eSee more about those rules\u003c/summary\u003e\n\u003cp\u003e\n\n\u003e 👉 No dependencies between Cozy Library\n\nA Cozy library should not add any other Cozy library.\nThose Cozy libraries should only be devDependencies + peerDependencies.\n\nWhy?\n- in order to reduce library size\n- in order to avoid dependencies cycle\n\n\u003e 👉 No react or react-dom  as dependencies in Cozy Library\n\nA Cozy library should not add React or React-DOM.\nThose packages should only be devDependencies + peerDependencies.\n\nWhy?\n- in order to have different versions of React and compatibility problem with Hooks\n\nWe follow the practise of [Material-UI](https://github.com/mui/material-ui/blob/master/package.json) or [React-Query](https://github.com/tannerlinsley/react-query/blob/master/package.json)\n\u003c/p\u003e\n\u003c/details\u003e\n\n# Unit Commit\n\nEach dependency upgrade should be inside its own commit, with the possible changes required by the upgrade.\n\nThis helps understanding which changes belong to dependency upgrade, and what belongs to the feature of the Pull Request. It is very useful when reverting commits.\n\n# Commit messages\n\nA git repository lives with an history that let developers or automatic procedure to find useful information.\n\nThey have to look like that:\n\n```\ntype(optional scope): Subject\n\noptional body\n\nfooter with references to issue tracker IDS\n```\n\n### Type\n\nOne of:\n\n- **feat**: a new feature\n- **fix**: a bug fix\n- **docs**: changes to documentation\n- **style**: formatting, missing semi colons, etc; _no code change_\n- **refactor**: refactoring production code; _no behavior change_\n- **test**: adding tests, refactoring test; _no production code change_\n- **chore**: updating build tasks, package manager configs, etc; _no production code change_\n\n### Scope (optional)\n\nThe scope should reflect the part of the codebase, or a specific Component, that is updated by the commit. It should be very concise (one or two words).\n\nExample: `feat(Chart): Redraw on data update`\n\nHere, the commit is updating the Chart component of the application. We know it directly from the commit message.\n\n### Subject\n\nSubjects should:\n\n- ideally be no greater than 50 characters\n- begin with a capital letter\n- do not end with a period\n- use an imperative tone to describe what a commit does, rather than what it did\n- use the past tense for a fix\n\n📌 A note about emojis in commit message\n\nYou can use emojis in your commit subject but, if so, you should add it after the type. You can also use emojis in body message anyway you want.\n[Suggested Emoji/task relations](https://github.com/slashsBin/styleguide-git-commit-message#suggested-emojis)\n\n```\n❌  Bad\n🚑 fix: when a list contains more than 50 items, the scroll is broken\n\n✅  Good\nfix: A too long list broke the scrolling 🚑\n```\n\n### Body aka commit description (optional but recommended)\n\nPay attention to commit descriptions. It is important that they describe the **why** of a solution and not only the what and especially the how. This makes it easier to understand architectural choices and decisions that seem clear at the time of implementation but will be much less clear to someone else in 6 months or 1 year.\n\nWhen writing a body, the **blank line between the title and the body is required** and you should **limit the length of each line to no more than 72 characters**.\n\nTo summarize:\n\n- it explains the reason for the change\n- it's searchable\n- it tells a story\n- it makes everyone a little smarter\n- it builds compassion and trust\n\nFor more details, see https://dhwthompson.com/2019/my-favourite-git-commit\n\n### Footer\n\nThe footer is optional and is used to reference issue tracker IDs.\n\n### Breaking change\n\nFollowing the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/), each commit introducing a breaking change must have a `BREAKING CHANGE: description`. The description should contain a migration path, i.e. a way to overcome the change for the apps using the impacted code.\n\n\n\u003cdetails\u003e\n    \u003csummary\u003eSee commit example here\u003c/summary\u003e\n\u003cp\u003e\n\n##### Example\n```git\nfeat: Summarize changes in around 50 characters or less\n\nMore detailed explanatory text, if necessary. Wrap it to about 72\ncharacters or so. In some contexts, the first line is treated as the\nsubject of the commit and the rest of the text as the body. The\nblank line separating the summary from the body is critical (unless\nyou omit the body entirely); various tools like `log`, `shortlog`\nand `rebase` can get confused if you run the two together.\n\nExplain the problem that this commit is solving. Focus on why you\nare making this change as opposed to how (the code explains that).\nAre there side effects or other unintuitive consequenses of this\nchange? Here's the place to explain them.\n\nFurther paragraphs come after blank lines.\n\n - Bullet points are okay, too\n\n - Typically a hyphen or asterisk is used for the bullet, preceded\n   by a single space, with blank lines in between, but conventions\n   vary here\n\nIf you use an issue tracker, put references to them at the bottom,\nlike this:\n\nResolves: #123\nSee also: #456, #789\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n# Pull requests\n\nBefore merging a PR, the following things must have been done:\n\n- Faithful integration of the mockups at all screen sizes\n- Tested on supported browsers, including responsive mode\n- Localized in English and French\n- All changes have test coverage\n- Updated README \u0026 CHANGELOG, if necessary\n\n# Travis\n\n## Deploy\n\nUse the `deploy` section of `travis.yml` instead of `after_success` along with checks on environment variables.\n\nTravis has lots of documentation to easily deploy on npm, github pages, ... you\ncan find documentation [here](https://docs.travis-ci.com/user/deployment/).\n\nIf you want use a specific command use [script](https://docs.travis-ci.com/user/deployment/script/),\nbut avoid environement variable checks in `after_success`.\n\n❌  Bad :\n\n```\nafter_success:\n- test $TRAVIS_BRANCH = \"master\" \u0026\u0026 test $TRAVIS_REPO_SLUG = \"cozy/cozy-realtime\" \u0026\u0026 test $TRAVIS_PULL_REQUEST = \"false\" \u0026\u0026 yarn travis-deploy-once \"yarn semantic-release\"\n```\n\n✅  Good\n\n```\ndeploy:\n- provider: script\n  skip_cleanup: true\n  script: yarn travis-deploy-once \"yarn semantic-release\"\n  on:\n    branch: master\n    repo: cozy/cozy-realtime\n```\n\n# Secrets\n\n## Encrypted variables\n\n### Travis\n\nAll encrypted variables must be set in `.travis.yml` not in the Travis web interface.\nThey should be preceded by the command to regenerate them. This makes regenerating\nthe variables easy and all the build information is versionned and peer-reviewed.\n\nWhen using `travis encrypt` with the `--add` flag, `travis-cli` will reformat the entire `.travis.yml` file and remove all comments. We suggest not using this flag at all.\n\nExample :\n\n```yml\n# NPM_TOKEN\n# To generate a new key: travis encrypt NPM_TOKEN=\u003ctoken\u003e -r cozy/cozy-realtime\n- secure: WDFj9IULpiNSR6h/i8dtmbm+h4hMAUk8EA8wve9sPrJV1GL5qsMgreMYV7uMx7S93K7h1EoILzS1877tLWJJdQ7f7UgakOUVXb41s0GOfQRznDYivqllYE+X9eUkh8gOBjjCF8G3dW4+w4bbY2X97ZC5hhxwQb3DgKWNdOuGLZXZRVmVNLR0XcEkR8p1CKJe4p/iNwianj2L9Q3wk1QvrBP74lwIJIY0i692fW9SKya/BTWGV+9mgGnR8TkAZUViZT2NygNpYxF4NDcXm1Kv2Y47e9Nr9ekGHuzTcCvT/K3hlpxzjo9VgY4lFvjr5izJ/vTScfB0JuHUs3SQFtrz9yI5DBx4OuUm7iJre2dRfUflJhO4KiCtmbZMh7CnBiMSTWFxPHxiD9kZaDU5EunfCRkWcdeSQTwo5bvscHzha7QNUsdzp/xMvOyhqvmoxXapzxymRzRaYntnvkVCZSJIGzHcc9FhsPRd2AQGyk5uffK4lAOVQ+D+d0WCh+5NagEQSPJ6rymsraJpdvR7OBMXVVAmJs76MnNWCQ3DPozIDkNxTxiWWXC02FZBeKrdnVoSLNUCj4jvdLwi4FmQbi2JNMk5zdOojqtt66LiZ8LtjnHzUXZ2dhfRL0URQm97UVagVmWNkte/6PaS/UeHCr193cwthbSFnanjHDclP0eBjvE=\n```\n\n## Secrets File\n\nBy default secrets file should not been versionned. But if the file will be available on the client side of your application, then we consider it public as said by firebase here (https://firebase.google.com/docs/projects/learn-more#config-files-objects). For instance, file as `google-services.json` can be versionned in our github repository. If you add this kind of file, please share the word on our security channel.\n\n# Feature flags\n\nMaster must always be in a state ready to be deployed in production.\nThat is why we use feature flags on each new routes or for each new features not ready to go to production.\n\nTo understand better how feature flags works, have a look to our internal wiki.\n\n# Release process\n\n![Release Schema](./cozyreleasediagram.png)\n\nYou can find more information about the recommended workflow [here](https://github.com/cozy/cozy-libs/tree/master/packages/cozy-app-publish#recommended-workflow)\n\n# Cozy Logo\n\n![Cozy Logo](./cozy_logo_small.svg?sanitize=true)\n\n## What is Cozy?\n\n![Cozy Logo](https://cdn.rawgit.com/cozy/cozy-guidelines/master/templates/cozy_logo_small.svg)\n\n[Cozy](http://cozy.io) is a platform that brings all your web services in the\nsame private space.  With it, your web apps and your devices can share data\neasily, providing you with a new experience. You can install Cozy on your own\nhardware where no one profiles you.\n\n## Community\n\nYou can reach the Cozy Community by:\n\n* Chatting with us on IRC [#cozycloud on Libera.Chat][libera]\n* Posting on our [Forum](https://forum.cozy.io)\n* Posting issues on the [Github repos](https://github.com/cozy/)\n* Mentioning us on [Twitter](http://twitter.com/mycozycloud)\n\n[transform-class-properties]: https://babeljs.io/docs/plugins/transform-class-properties/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcozy%2Fcozy-guidelines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcozy%2Fcozy-guidelines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcozy%2Fcozy-guidelines/lists"}