{"id":13432837,"url":"https://github.com/vislyhq/stretch","last_synced_at":"2025-05-14T07:09:40.555Z","repository":{"id":41176317,"uuid":"159668508","full_name":"vislyhq/stretch","owner":"vislyhq","description":"High performance flexbox implementation written in rust","archived":false,"fork":false,"pushed_at":"2023-01-26T16:14:25.000Z","size":44493,"stargazers_count":2010,"open_issues_count":47,"forks_count":109,"subscribers_count":36,"default_branch":"master","last_synced_at":"2025-04-11T03:38:09.492Z","etag":null,"topics":["android","cross-platform","flexbox","ios","rust"],"latest_commit_sha":null,"homepage":"https://vislyhq.github.io/stretch/","language":"Rust","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/vislyhq.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":"2018-11-29T13:14:28.000Z","updated_at":"2025-04-06T10:48:23.000Z","dependencies_parsed_at":"2023-02-02T20:15:25.193Z","dependency_job_id":null,"html_url":"https://github.com/vislyhq/stretch","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vislyhq%2Fstretch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vislyhq%2Fstretch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vislyhq%2Fstretch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vislyhq%2Fstretch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vislyhq","download_url":"https://codeload.github.com/vislyhq/stretch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254092788,"owners_count":22013290,"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":["android","cross-platform","flexbox","ios","rust"],"created_at":"2024-07-31T02:01:17.332Z","updated_at":"2025-05-14T07:09:35.535Z","avatar_url":"https://github.com/vislyhq.png","language":"Rust","funding_links":[],"categories":["Rust","Graphic Layout Engine"],"sub_categories":["Rust 2D renderer"],"readme":"# Stretch\n[![CircleCI](https://circleci.com/gh/vislyhq/stretch.svg?style=svg)](https://circleci.com/gh/vislyhq/stretch)\n[![Cargo](https://img.shields.io/crates/v/stretch.svg)](https://crates.io/crates/stretch)\n[![npm](https://img.shields.io/npm/v/stretch-layout.svg)](https://www.npmjs.com/package/stretch-layout)\n[![cocoapods](https://img.shields.io/cocoapods/v/StretchKit.svg)](https://cocoapods.org/pods/StretchKit)\n[![bintray](https://api.bintray.com/packages/visly/maven/stretch-kotlin-bindings/images/download.svg)](https://bintray.com/visly/maven/stretch-kotlin-bindings)\n\nStretch is an implementation of Flexbox written in [Rust](https://www.rust-lang.org). The goal of stretch is to provide a solid foundation for layout across all platforms with a specific focus on mobile. Long term we want stretch to not only support flexbox but also many other layout algorithms such as grid layout. Stretch was made for and powers https://visly.app.\n\n## Goals\nBefore using or contributing to stretch it is good to be aware of the core goals of the project. These are goals we are working towards, not necessarily features we currently support.\n\n- High performance\n- Cross platform\n- Small binary size\n- Support multiple layout systems\n- Multi-threaded layout\n- Language bindings for most common languages\n\n## Supported Platforms\n\n- Rust\n- Android\n- iOS\n- JavaScript / TypeScript\n\n## Usage\nStretch is built in Rust but comes with bindings to multiple languages and platforms so you can use it in a way that feels natural to your project.\n\n### Rust\n```toml\n# Cargo.toml\n\n[dependencies]\nstretch = \"0.3.2\"\n```\n\n```rust\n// main.rs\n\nuse stretch::geometry::Size;\nuse stretch::style::*;\n\nfn main() -\u003e Result\u003c(), stretch::Error\u003e {\n    let mut stretch = stretch::node::Stretch::new();\n    \n    let child = stretch.new_node(\n        Style { size: Size { width: Dimension::Percent(0.5), height: Dimension::Auto }, ..Default::default() },\n        vec![],\n    )?;\n\n    let node = stretch.new_node(\n        Style {\n            size: Size { width: Dimension::Points(100.0), height: Dimension::Points(100.0) },\n            justify_content: JustifyContent::Center,\n            ..Default::default()\n        },\n        vec![child],\n    )?;\n\n    stretch.compute_layout(node, Size::undefined())?;\n    dbg!(stretch.layout(node)?);\n}\n\n```\n\n### Android\n```groovy\n// Build.gradle\n\nandroid {\n    splits {\n        abi {\n            enable true\n        }\n    }\n}\n\ndependencies {\n    implementation 'app.visly.stretch:stretch:0.3.2'\n}\n```\n\n```kotlin\n// MainActivity.kt\n\nval node = Node(\n  Style(size = Size(Dimension.Points(100f), Dimension.Points(100f)), justifyContent = JustifyContent.Center), \n  listOf(\n    Node(Style(size = Size(Dimension.Percent(0.5f), Dimension.Percent(0.5f))), listOf())\n  ))\n\nval layout = node.computeLayout(Size(null, null))\nLog.d(TAG, \"width: ${layout.width}, height: ${layout.height}\")\n```\n\n### iOS\n```ruby\n# Podfile\n\npod 'StretchKit', '~\u003e 0.3.2'\n```\n\n```swift\n// ViewController.swift\n \nlet node = Node(\n  style: Style(size: Size(width: .points(100.0), height: .points(100.0)), justifyContent: .center), \n  children: [\n    Node(style: Style(size: Size(width: .percent(0.5), height: .percent(0.5))), children: [])\n  ])\n  \nlet layout = node.computeLayout(thatFits: Size(width: nil, height: nil))\nprint(\"width: \\(layout.width), height: \\(layout.height)\")\n```\n\n### JavaScript\n```bash\n\u003e npm install --save stretch-layout\n```\n\n```javascript\n// index.js\n\nimport { Allocator, Node, JustifyContent } from 'stretch-layout';\n\nconst allocator = new Allocator();\nconst node = new Node(allocator, {width: 100, height: 100, justifyContent: JustifyContent.Center});\nnode.addChild(new Node(allocator, {width: '50%', height: '50%'}));\nconst layout = node.computeLayout();\n\nconsole.log(layout.width, layout.height);\n```\n\n## Contributing\nContributions are very welcome. Though we ask that you open an issue or pull request early in the process (before writing code) so we can discuss solutions and additions before you start spending time on implementing them. There are some specific areas where we would be extra happy to receive contributions in.\n\n- Binary size reduction\n- Runtime performance\n- Ensure build / test environment works well on non macOS platforms\n- Alternate layout systems (grid layout perhaps?)\n- Web compatibility tests\n- RTL support\n- Platform bindings\n- API improvements\n- Documentation \u0026 Examples\n\n### Installation\nIf you don't have Rust installed you have to do that first as well as install some components that we make use of to format and lint the codebase. For more on Rust see their [website](https://www.rust-lang.org).\n\n```bash\ncurl https://sh.rustup.rs -sSf | sh\nrustup component add rustfmt\nrustup component add clippy\n```\n\nOnce that is done you can clone the repo and do some sanity checks to make sure everything is working correctly.\n\n```bash\ngit clone https://github.com/vislyhq/stretch.git\ncd stretch\ncargo test\n```\n\nIf you have made any changes to the API you should also update and run tests for all the platform bindings located in `/bindings/*`.\n\n### Testing\nStretch is tested by validating that layouts written in stretch perform the same as in Chrome. This is done by rendering an equivalent layout in HTML and then generating a Rust test case which asserts that the resulting layout is the same when run through stretch.\n\nYou can run these tests without setting up a webdriver environment but if you are looking to add any test case you will need to install [chromedriver](http://chromedriver.chromium.org). If you are developing on macOS this is easy to do through brew.\n\n```bash\nbrew tap homebrew/cask\nbrew cask install chromedriver\n```\n\nOnce you have chromedriver installed and available in `PATH` you can re-generate all tests by running `cargo run --package gentest`.\n\nTo add a new test case add another HTML file to `/test_fixtures` following the current tests as a template for new tests.\n\n### Benchmarking\nBenchmarks build on the same infrastructure as testing, and actually benchmarks are automatically generated from test fixtures just like tests. Run `cargo bench` to run benchmarks locally.\n\n## Relationship to Yoga\n[Yoga](https://www.yogalayout.com) is a cross-platform implementation of Flexbox written in C. Yoga is a fantastic project but has some fundamental issues which we hope to resolve. Compared to Yoga we aim to have a stronger adherence to web standards, a flexible architecture eventually supporting multiple layout algorithms, and future performance improvements including multi-threaded layout. In addition to this we aim to use a safer language with a more modern codebase.\n\n# LICENCE\n```\nCopyright (c) 2018 Visly Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvislyhq%2Fstretch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvislyhq%2Fstretch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvislyhq%2Fstretch/lists"}