{"id":15823888,"url":"https://github.com/zoriya/yoshiki","last_synced_at":"2025-08-24T06:39:02.807Z","repository":{"id":63691368,"uuid":"561445573","full_name":"zoriya/yoshiki","owner":"zoriya","description":"Universal react (native) CSS-in-JS library","archived":false,"fork":false,"pushed_at":"2023-12-01T22:23:25.000Z","size":3924,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-04T21:45:05.954Z","etag":null,"topics":["css","css-in-js","react","react-native"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/yoshiki","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zoriya.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-03T17:52:02.000Z","updated_at":"2024-06-14T22:41:33.000Z","dependencies_parsed_at":"2023-02-18T19:00:47.202Z","dependency_job_id":"d566bdda-4cbe-4037-b455-14fb5dbaf734","html_url":"https://github.com/zoriya/yoshiki","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoriya%2Fyoshiki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoriya%2Fyoshiki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoriya%2Fyoshiki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoriya%2Fyoshiki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zoriya","download_url":"https://codeload.github.com/zoriya/yoshiki/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232670353,"owners_count":18558569,"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":["css","css-in-js","react","react-native"],"created_at":"2024-10-05T08:24:01.737Z","updated_at":"2025-01-06T03:51:24.679Z","avatar_url":"https://github.com/zoriya.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Yoshiki\n\n## Features\n\n- Same interface for React, React Native and React Native Web\n- Universal API working for builtins, any component library or your own\n- Breakpoints as objects\n- User defined theme support\n- Shorthands (`m` for `margin`, `paddingX` for `paddingLeft` and `paddingRight`...)\n- State handling (hover, focused, pressed) with child support\n- Atomic CSS generation\n- Automatic vendor prefixing\n- SSR support\n- Automatic theme (light/dark)\n\n## Installation\n\nAs any other npm package, simply run\n\n`yarn add yoshiki`\n\nor\n\n`npm install --save yoshiki`\n\nAs most react-native packages, you need to transpile this package. This will be done automatically with React native or expo\nbut if you use this elsewhere you need to tweek your settings to automatically transpile it.\n\nFor example, in next.js, you need to add the `transpilePackages` line on `next.config.js` like so:\n\n```js\nconst nextConfig = {\n\treactStrictMode: true,\n\tswcMinify: true,\n\ttranspilePackages: [\"yoshiki\"],\n};\n\nmodule.exports = nextConfig;\n```\n\n## Usage\n\n```tsx\nimport { Stylable, useYoshiki } from \"yoshiki\";\n\nconst ColoredDiv = ({ color }: { color: string }) =\u003e {\n\tconst { css } = useYoshiki();\n\n\treturn (\n\t\t\u003cdiv\n\t\t\t{...css({\n\t\t\t\tbackgroundColor: color,\n\t\t\t\theight: { xs: \"13%\", lg: \"25%\" },\n\t\t\t\tpaddingX: (theme) =\u003e theme.spaccing,\n\t\t\t\tm: 1,\n\t\t\t\tfocus: {\n\t\t\t\t\tself: {\n\t\t\t\t\t\tbg: \"green\",\n\t\t\t\t\t},\n\t\t\t\t\ttext: {\n\t\t\t\t\t\tcolor: \"black\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t})}\n\t\t\u003e\n\t\t\t\u003cp {...css([{ color: \"white\" }, \"text\"])}\u003eText inside the colored div.\u003c/p\u003e\n\t\t\u003c/div\u003e\n\t);\n};\n```\n\nOr for React Native components, simply use the `yoshiki/native` import.\nNotice that the only difference between the two are the components and the import.\n\n```tsx\nimport { Text, View } from \"react-native\";\nimport { Stylable, useYoshiki } from \"yoshiki/native\";\n\nconst ColoredBox = ({ color }: { color: string }) =\u003e {\n\tconst { css } = useYoshiki();\n\n\treturn (\n\t\t\u003cView\n\t\t\t{...css({\n\t\t\t\tbackgroundColor: color,\n\t\t\t\theight: { xs: \"13%\", lg: \"25%\" },\n\t\t\t\tpaddingX: (theme) =\u003e theme.spaccing,\n\t\t\t\tm: 1,\n\t\t\t\tfocus: {\n\t\t\t\t\tself: {\n\t\t\t\t\t\tbg: \"green\",\n\t\t\t\t\t},\n\t\t\t\t\ttext: {\n\t\t\t\t\t\tcolor: \"black\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t})}\n\t\t\u003e\n\t\t\t\u003cText {...css([{ color: \"white\" }, \"text\"])}\u003eText inside the colored div.\u003c/Text\u003e\n\t\t\u003c/View\u003e\n\t);\n};\n```\n\nYou can also use multiple style objects to apply some conditions or a breakpoint to multiple styles at once:\n\n```tsx\nimport { useState } from \"react\";\nimport { Text, View } from \"react-native\";\nimport { Stylable, useYoshiki, md } from \"yoshiki/native\";\n\nconst ColoredBox = ({ color }: { color: string }) =\u003e {\n\tconst { css } = useYoshiki();\n\tconst [state, setState] = useState(state);\n\n\treturn (\n\t\t\u003cView\n\t\t\t{...css([\n\t\t\t\t{\n\t\t\t\t\tbackgroundColor: color,\n\t\t\t\t\theight: { xs: \"13%\", lg: \"25%\" },\n\t\t\t\t},\n\t\t\t\tstate \u0026\u0026 {\n\t\t\t\t\tpaddingX: (theme) =\u003e theme.spaccing,\n\t\t\t\t\tm: 1,\n\t\t\t\t},\n\t\t\t\tmd({\n\t\t\t\t\twidth: rem(3),\n\t\t\t\t}),\n\t\t\t])}\n\t\t\u003e\n\t\t\t\u003cText {...css({ color: \"white\" })}\u003eText inside the colored box.\u003c/Text\u003e\n\t\t\u003c/View\u003e\n\t);\n};\n```\n\nThis syntax, as any others of Yoshiki works on both React and React Native.\n\n## Recipes\n\n### Customize your own components\n\nIn order to theme your own components, you need to forward some props to the root element like the following example:\n\n```tsx\nconst Example = (props) =\u003e {\n\treturn (\n\t\t\u003cdiv {...props}\u003e\n\t\t\t\u003cp\u003eExample component\u003c/p\u003e\n\t\t\u003c/div\u003e\n\t);\n};\n```\n\nIf you want to use yoshiki to theme your component and allow others components to override styles, pass\nthe props to the `css` function.\n\n```tsx\nimport { useYoshiki } from \"yoshiki/web\";\n\nconst Example = (props) =\u003e {\n\tconst { css } = useYoshiki();\n\n\treturn (\n\t\t\u003cdiv {...css({ background: \"black\" }, props)}\u003e\n\t\t\t\u003cp\u003eExample component\u003c/p\u003e\n\t\t\u003c/div\u003e\n\t);\n};\n```\n\nTo stay type-safe and ensure you don't forget to pass down the props, yoshiki exposes the `Stylable` type, so you can do:\n\n```tsx\nimport { ReactNode } from \"react\";\nimport { useYoshiki, Stylable } from \"yoshiki/web\";\n// or\n// import { useYoshiki, Stylable } from \"yoshiki/native\";\n\nconst Example = (props: Stylable) =\u003e {\n\tconst { css } = useYoshiki();\n\n\treturn (\n\t\t\u003cdiv {...css({ background: \"black\" }, props)}\u003e\n\t\t\t\u003cExampleText {...css({ padding: \"15px\" })}\u003eExample component\u003c/ExampleText\u003e\n\t\t\u003c/div\u003e\n\t);\n};\n\nconst ExampleText = ({ children, ...props }: { children: ReactNode } \u0026 Stylable) =\u003e {\n\tconst { css } = useYoshiki();\n\n\treturn \u003cp {...css({ color: \"white\", padding: \"10px\" }, props)}\u003e{children}\u003c/p\u003e;\n};\n```\n\nYoshiki will handle overrides so the `ExampleText`'s p element will have a padding of `15px`.\n\n### Server Side Rendering (SSR)\n\n#### Generic\n\nTo support server side rendering, you need to create a style registry and wrap your app with a `StyleRegistryProvider`.\n\n```tsx\nimport { StyleRegistryProvider, createStyleRegistry } from \"yoshiki/web\";\n\nconst registry = createStyleRegistry();\n\nconst html = renderToString(\n\t\u003cStyleRegistryProvider registry={registry}\u003e\n\t\t\u003cApp /\u003e\n\t\u003c/StyleRegistryProvider\u003e,\n);\n\n// A list of classes to append to your html head.\nconst style = registry.flush();\n```\n\n#### Next\n\nStarting Next 13, a new hook is available to do this easily. If you have not yet migrated to next 13, don't worry, there is another solution below.\n\nWrap your app with the following component:\n\n```tsx\nimport { ReactNode, useMemo } from \"react\";\nimport { useServerInsertedHTML } from \"next/navigation\";\nimport { createStyleRegistry, StyleRegistryProvider } from \"yoshiki\";\n\nconst RootRegistry = ({ children }: { children: ReactNode }) =\u003e {\n\tconst registry = useMemo(() =\u003e createStyleRegistry(), []);\n\n\tuseServerInsertedHTML(() =\u003e {\n\t\treturn registry.flushToComponent();\n\t});\n\n\treturn \u003cStyleRegistryProvider registry={registry}\u003e{children}\u003c/StyleRegistryProvider\u003e;\n};\n\nconst App = ({ Component, pageProps }: AppProps) =\u003e {\n\treturn (\n\t\t\u003cRootRegistry\u003e\n\t\t\t\u003cComponent {...pageProps} /\u003e\n\t\t\u003c/RootRegistry\u003e\n\t);\n};\n```\n\n#### Next \u003c 13\n\nSimply use the following `getInitialProps` inside the `pages/_document.tsx` file.\n\n```tsx\nimport { StyleRegistryProvider, createStyleRegistry } from \"yoshiki/web\";\nimport Document, { DocumentContext } from \"next/document\";\n\nDocument.getInitialProps = async (ctx: DocumentContext) =\u003e {\n\tconst renderPage = ctx.renderPage;\n\tconst registry = createStyleRegistry();\n\n\tctx.renderPage = () =\u003e\n\t\trenderPage({\n\t\t\tenhanceApp: (App) =\u003e (props) =\u003e {\n\t\t\t\treturn (\n\t\t\t\t\t\u003cStyleRegistryProvider registry={registry}\u003e\n\t\t\t\t\t\t\u003cApp {...props} /\u003e\n\t\t\t\t\t\u003c/StyleRegistryProvider\u003e\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\tconst props = await ctx.defaultGetInitialProps(ctx);\n\treturn {\n\t\t...props,\n\t\tstyles: (\n\t\t\t\u003c\u003e\n\t\t\t\t{props.styles}\n\t\t\t\t{registry.flushToComponent()}\n\t\t\t\u003c/\u003e\n\t\t),\n\t};\n};\n\nexport default Document;\n```\n\n### Theme\n\nTo use the theme, you need to wrap your app with a `ThemeProvider`. If you are using typescript, you will also\nneed to use module augmentation to add your properties to the theme object.\n\n```tsx\nimport { Theme, ThemeProvider, useYoshiki } from \"yoshiki/web\";\n\ndeclare module \"yoshiki\" {\n\texport interface Theme {\n\t\tspacing: string;\n\t\tname: string;\n\t}\n}\n\nconst defaultTheme: Theme = {\n\tspacing: \"24px\",\n\tname: \"yoshiki\",\n};\n\nconst App = () =\u003e {\n\treturn (\n\t\t\u003cThemeProvider theme={defaultTheme}\u003e\n\t\t\t\u003cAppName /\u003e\n\t\t\u003c/ThemeProvider\u003e\n\t);\n};\n\nconst AppName = () =\u003e {\n\tconst { css, theme } = useYoshiki();\n\n\treturn \u003cp {...css({ padding: (theme) =\u003e theme.spacing })}\u003e{theme.name}\u003c/p\u003e;\n};\n```\n\n### Automatic theme\n\nIf you have a light and dark theme, you may want to automatically switching between the two based on user preferences.\nYoshiki support this directly with the css property, you can use the `useAutomaticTheme` to get the automatic version\nof a light/dark theme.\n\nThis approach works with SSR.\n\n```tsx\nimport { useYoshiki, useAutomaticTheme } from \"yohsiki/web\";\n\nconst App = () =\u003e {\n\tconst theme = {\n\t\tlight: { background: \"white\", text: \"black\" },\n\t\tdark: { background: \"black\", text: \"white\" },\n\t};\n\tconst auto = useAutomaticTheme(\"key\", theme);\n\tconst { css } = useYoshiki();\n\n\treturn (\n\t\t\u003cdiv {...css({ bg: auto.background })}\u003e\n\t\t\t\u003cp {...css({ textColor: auto.text })}\u003eAutomatic theme\u003c/p\u003e\n\t\t\u003c/div\u003e\n\t);\n};\n```\n\n## API\n\n### useYoshiki\n\nThe most used function will be `useYoshiki`:\n\n```typescript\nconst { css, theme } = useYoshiki;\n```\n\nThe `theme` variable is the one returned from `useTheme` and the css function has the following signature:\n\n```typescript\ncss: (css: CssObject, leftovers: object) =\u003e Props;\n```\n\nThe first parameter is a css object, in react web that means a dictionary of css key-values. On React Native that means\na `ViewStyle`, a `TextStyle` or an `ImageStyle`. Yoshiki will unsure type safety by returning the style object needed\nfor your arguments.\n\nThe css object can also take the keys `hover`, `focus` and `press`. Thoses keys should be filled with a dictionary of\nkeys and style properties. You can then use thoses keys on a child component by putting it as a string in the `css`\ncall. Yoshiki will apply the style object to the object only when it should. You can also use the special value `self`\nto directly theme the component that defines the state.\n\nThe leftover parameter is here to allow your component to be customized by yoshiki. See [Customize your own components](#customize-your-own-components)\nfor more details.\n\n### useTheme\n\n```typescript\nconst theme = useTheme();\n```\n\nSimply return the theme object you defined with a Theme Provider see [Theme](#theme) for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzoriya%2Fyoshiki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzoriya%2Fyoshiki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzoriya%2Fyoshiki/lists"}