{"id":14981018,"url":"https://github.com/yishn/jsx-tikzcd","last_synced_at":"2025-10-29T04:31:28.645Z","repository":{"id":57286595,"uuid":"99939741","full_name":"yishn/jsx-tikzcd","owner":"yishn","description":"Render tikzcd diagrams with JSX.","archived":false,"fork":false,"pushed_at":"2020-01-25T13:37:27.000Z","size":154,"stargazers_count":59,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-09-29T05:03:42.701Z","etag":null,"topics":["category-theory","diagram","jsx","latex","tikz","tikzcd"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/yishn.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}},"created_at":"2017-08-10T15:46:25.000Z","updated_at":"2024-08-29T05:30:15.000Z","dependencies_parsed_at":"2022-09-09T21:52:08.214Z","dependency_job_id":null,"html_url":"https://github.com/yishn/jsx-tikzcd","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yishn%2Fjsx-tikzcd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yishn%2Fjsx-tikzcd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yishn%2Fjsx-tikzcd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yishn%2Fjsx-tikzcd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yishn","download_url":"https://codeload.github.com/yishn/jsx-tikzcd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219858397,"owners_count":16556045,"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":["category-theory","diagram","jsx","latex","tikz","tikzcd"],"created_at":"2024-09-24T14:02:44.708Z","updated_at":"2025-10-29T04:31:23.339Z","avatar_url":"https://github.com/yishn.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jsx-tikzcd [![Build Status](https://travis-ci.org/yishn/jsx-tikzcd.svg?branch=master)](https://travis-ci.org/yishn/jsx-tikzcd)\n\nRender `tikzcd` diagrams with JSX.\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Getting Started](#getting-started)\n    - [Installation](#installation)\n    - [Set Up](#set-up)\n    - [Render](#render)\n    - [Components](#components)\n    - [Gluing](#gluing)\n    - [Duality](#duality)\n- [Documentation](#documentation)\n\n## Introduction\n\n`tikzcd` is a powerful LaTeX package that can draw beautiful diagrams used in mathematics, especially category theory. However, its syntax is primarily based on the appearance, not the semantics, which makes it difficult to, say, change the position of a single node without having to redefine the edges.\n\n`jsx-tikzcd` can turn a simple, semantic JSX tree consisting of nodes and edges into `tikzcd` code. The following JSX\n\n~~~js\n// JSX code\n\n\u003cDiagram\u003e\n    \u003cNode key=\"prod\" position={[0, 0]} value=\"X\\times_Z Y\" /\u003e\n    \u003cNode key=\"a\" position={[1, 0]} value=\"X\" /\u003e\n    \u003cNode key=\"b\" position={[0, 1]} value=\"Y\" /\u003e\n    \u003cNode key=\"base\" position={[1, 1]} value=\"Z\" /\u003e\n\n    \u003cEdge from=\"a\" to=\"base\" /\u003e\n    \u003cEdge from=\"b\" to=\"base\" /\u003e\n    \u003cEdge from=\"prod\" to=\"a\" value=\"p_1\" /\u003e\n    \u003cEdge from=\"prod\" to=\"b\" value=\"p_2\" alt /\u003e\n\u003c/Diagram\u003e\n~~~\n\nyields\n\n~~~latex\n% LaTeX code\n\n\\begin{tikzcd}\nX\\times_Z Y \\arrow[r, \"p_1\"] \\arrow[d, \"p_2\"'] \u0026 X \\arrow[d] \\\\\nY \\arrow[r] \u0026 Z\n\\end{tikzcd}\n~~~\n\nwhich renders into\n\n![Demo](./demo.png)\n\n## Getting Started\n\n### Installation\n\nYou can install jsx-tikzcd using npm:\n\n~~~\nnpm install jsx-tikzcd\n~~~\n\n### Set Up\n\nMake sure you have JSX set up correctly in Babel:\n\n~~~js\n{\n    \"plugins\": [\n        [\"transform-react-jsx\", {\"pragma\": \"h\"}]\n    ]\n}\n~~~\n\n### Render\n\nThen you can render TikZ diagrams like this:\n\n~~~js\nimport {h, render, Diagram, Node, Edge} from 'jsx-tikzcd'\n\nlet tex = render(\n    \u003cDiagram\u003e\n        \u003cNode key=\"prod\" position={[0, 0]} value=\"X\\times_Z Y\" /\u003e\n        \u003cNode key=\"a\" position={[1, 0]} value=\"X\" /\u003e\n        \u003cNode key=\"b\" position={[0, 1]} value=\"Y\" /\u003e\n        \u003cNode key=\"base\" position={[1, 1]} value=\"Z\" /\u003e\n\n        \u003cEdge from=\"a\" to=\"base\" /\u003e\n        \u003cEdge from=\"b\" to=\"base\" /\u003e\n        \u003cEdge from=\"prod\" to=\"a\" value=\"p_1\" /\u003e\n        \u003cEdge from=\"prod\" to=\"b\" value=\"p_2\" alt /\u003e\n    \u003c/Diagram\u003e\n)\n~~~\n\n### Components\n\nYou can define your own components and use them to make higher-order components just like in React.\n\n~~~js\nimport {h, render, Component, Diagram, Node, Edge} from 'jsx-tikzcd'\n\nclass Arrow extends Component {\n    render() {\n        if (this.props.children.length \u003c 2) return\n\n        let [x, y] = this.props.position || [0, 0]\n        let [dx, dy] = this.props.direction || [1, 0]\n        let [a, b, ] = this.props.children\n\n        return \u003cDiagram\u003e\n            \u003cNode {...a.props} position={[x, y]} /\u003e\n            \u003cNode {...b.props} position={[x + dx, y + dy]} /\u003e\n\n            \u003cEdge from={a.key} to={b.key} /\u003e\n        \u003c/Diagram\u003e\n    }\n}\n\nlet tex = render(\n    \u003cDiagram\u003e\n        \u003cArrow\u003e\n            \u003cNode key=\"x\" value=\"X\" /\u003e\n            \u003cNode key=\"y\" value=\"Y\" /\u003e\n        \u003c/Arrow\u003e\n\n        \u003cNode key=\"z\" value=\"Z\" position={[2, 0]} /\u003e\n        \u003cEdge from=\"y\" to=\"z\" /\u003e\n    \u003c/Diagram\u003e\n)\n~~~\n\njsx-tikzcd doesn't support state and tracking state changes, so every component is a pure component and can be written as a function as well:\n\n~~~js\nconst Arrow = function(props) {\n    if (props.children.length \u003c 2) return\n\n    let [x, y] = props.position || [0, 0]\n    let [dx, dy] = props.direction || [1, 0]\n    let [a, b, ] = props.children\n\n    return \u003cDiagram\u003e\n        \u003cNode {...a.props} position={[x, y]} /\u003e\n        \u003cNode {...b.props} position={[x + dx, y + dy]} /\u003e\n\n        \u003cEdge from={a.key} to={b.key} /\u003e\n    \u003c/Diagram\u003e\n}\n~~~\n\n### Gluing\n\nNodes with the same key will be merged and collapsed into one single node. This is useful to glue multiple sub components together.\n\n~~~js\nlet tex = render(\n    \u003cDiagram\u003e\n        \u003cArrow\u003e\n            \u003cNode key=\"x\" value=\"X\" /\u003e\n            \u003cNode key=\"y\" value=\"Y\" /\u003e\n        \u003c/Arrow\u003e\n\n        {/* Gluing at y */}\n\n        \u003cArrow position={[1, 0]}\u003e\n            \u003cNode key=\"y\" /\u003e\n            \u003cNode key=\"z\" value=\"Z\" /\u003e\n        \u003c/Arrow\u003e\n    \u003c/Diagram\u003e\n)\n\n// \\begin{tikzcd}\n// X \\arrow[r] \u0026 Y \\arrow[r] \u0026 Z\n// \\end{tikzcd}\n~~~\n\nIf there are conflicting attributes, the one that was defined last is used, i.e. attributes that come after will overwrite attributes that came before. Keep in mind that edges are not glued; you can define multiple edges between two nodes.\n\n### Duality\n\nIn category theory, there's this concept of an opposite category, in which every arrow of a diagram is reversed. It's possible to automate this process in jsx-tikzcd by adding the attribute `co` to a Diagram:\n\n~~~js\nlet tex = render(\n    \u003cDiagram co\u003e\n        \u003cArrow\u003e\n            \u003cNode key=\"x\" value=\"X\" /\u003e\n            \u003cNode key=\"y\" value=\"Y\" /\u003e\n        \u003c/Arrow\u003e\n\n        \u003cArrow position={[1, 0]}\u003e\n            \u003cNode key=\"y\" /\u003e\n            \u003cNode key=\"z\" value=\"Z\" /\u003e\n        \u003c/Arrow\u003e\n    \u003c/Diagram\u003e\n)\n\n// \\begin{tikzcd}\n// X \u0026 Y \\arrow[l] \u0026 Z \\arrow[l]\n// \\end{tikzcd}\n~~~\n\nAlternatively, you can use the `corender` function of jsx-tikzcd:\n\n~~~js\nimport {h, corender, Diagram, Node, Edge} from 'jsx-tikzcd'\n\nlet tex = corender(\n    \u003cDiagram\u003e\n        \u003cArrow\u003e\n            \u003cNode key=\"x\" value=\"X\" /\u003e\n            \u003cNode key=\"y\" value=\"Y\" /\u003e\n        \u003c/Arrow\u003e\n\n        \u003cArrow position={[1, 0]}\u003e\n            \u003cNode key=\"y\" /\u003e\n            \u003cNode key=\"z\" value=\"Z\" /\u003e\n        \u003c/Arrow\u003e\n    \u003c/Diagram\u003e\n)\n~~~\n\n## Documentation\n\n### `render` and `corender`\n\n#### Arguments\n\n* `vnode` [`\u003cDiagram/\u003e`](#diagram) - The diagram to render\n* `options` `\u003cObject\u003e` *(optional)*\n    * `align` `\u003cBoolean\u003e` - Determines whether the generated code will vertically align at `\u0026`. Default: `false`\n\nReturns a string which contains the corresponding LaTeX code to the given diagram.\n\n### `\u003cDiagram/\u003e`\n\n#### Props\n\n* `co` `\u003cBoolean\u003e` *(optional)* - Determines whether to reverse all edges\n* `options` `\u003cString\u003e` *(optional)* - `tikzcd` environment options\n\nThese attributes only work in the root node, i.e. the node that's passed to `render` or `corender`.\n\n### `\u003cNode/\u003e`\n\n#### Props\n\n* `key` `\u003cString\u003e`\n* `position` `\u003cInteger[]\u003e` - Has the form `[x, y]`, negative integers are also allowed\n* `value` `\u003cString\u003e` *(optional)* - LaTeX label\n\n### `\u003cEdge/\u003e`\n\n#### Props\n\n* `from` `\u003cString\u003e` - Key of the start node\n* `to` `\u003cString\u003e` - Key of the end node\n* `value` `\u003cString\u003e` *(optional)* - LaTeX label\n* `labelPosition` `\u003cString\u003e` *(optional)* - One of `\"left\"`, `\"right\"`, and `\"inside\"`\n* `alt` `\u003cBoolean\u003e` *(optional)* - Determines whether the label is positioned on the other side of the arrow\n* `args` `\u003cString[]\u003e` *(optional)* - Additional tikzcd arguments of edge, e.g. `\"hook\"`, `\"two heads\"`, etc.\n\n## Related\n\n* [tikzcd-editor](https://github.com/yishn/tikzcd-editor) - A simple visual editor for creating commutative diagrams.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyishn%2Fjsx-tikzcd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyishn%2Fjsx-tikzcd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyishn%2Fjsx-tikzcd/lists"}