Skip to content

Latest commit

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Raspberry - JSX as JSON

Raspberry is a format for expressing JSX files as plain JSON. This makes it easier to programmatically generate and modify React & React Native code.

Why?

The point of Raspberry to use some other system (GUI or command line) to generate actual React / RN code. This is useful for creating 'App Builder' type systems, managing your app from a CMS or programmatically generating whitelabel versions of an app.

Raspberry differs from other JSON/XML formats as it is designed specifically for JSX. This includes state logic, hooks and conditional rendering.

Because of this, Raspberry is provided as a Node script, and is not designed to be run in the front end.

How it looks

{
"meta": {
"fileName": "example",
"export": {
"name": "{Example}"
}
},
"bodyImports": [
{
"name": "React",
"from": "react"
},
{
"name": "{useState}",
"from": "react"
}
],
"body": "const x = true; const [textState, setTextState] = useState('Welcome to React Native');",
"markup": {
"import": {
"name": "{View}",
"from": "react-native"
},
"props": {
"style": {
"flexDirection": "row",
"display": "flex",
"alignItems": "center"
}
},
"children": [
{
"import": {
"name": "{TouchableOpacity}",
"from": "react-native"
},
"logic": {
"renderIf": "x === true"
},
"props": {
"onPress": "() => setTextState('Rendered with Raspberry')"
},
"children": [
{
"import": {
"name": "{Text}",
"from": "react-native"
},
"props": {
"style": {
"textAlign": "right",
"color": "red"
},
"numberOfLines": 1
},
"stringChild": "{textState}"
}
]
}
]
}
}

As you can see, everything we would expect to find in JSX is modelled in JSON.

What that makes

After prettifying, this is the output:

importReactfrom'react';import{useState}from'react';import{View}from'react-native';import{TouchableOpacity}from'react-native';import{Text}from'react-native';exportconstExample=()=>{constx=true;const[textState,setTextState]=useState('Welcome to React Native');return(<Viewstyle={{"flexDirection": "row","display": "flex","alignItems": "center"}}><TouchableOpacityonPress={()=>setTextState('Rendered with Raspberry')}><Textstyle={{"textAlign": "right","color": "red"}}numberOfLines={1}>{textState}</Text></TouchableOpacity></View>)}

Converting

It's up to you to generate the Raspberry file. To convert it to JSX, simply run.

node ./raspberry-cli.js path/to/input.raspberry.json path/to/output.jsx

Your file will be created, or overwritten if it already exists.

Specification v1.0

typeRsImport={name: string,// {Component} for named import, or Componentfrom: string// my-package}typeRsComponent={import: RsImport,props: object,// Any normal props you would have in React / RNchildren?: [RsComponent]stringChild?: string,// Components like <Text/> take a string child.logic?: {renderIf: string// This string should return true of false when passed to eval()}}typeRsFile={meta: {fileName: string,export: {name: string// Currently only supports named export},},bodyImports: [RsImport],// Any imports required by the body stringbody: string,// All code that is not part of the return()markup: RsComponent}

Caveats

  • No support for class-based components
  • Currently only supports named export

Future Improvements

  • Optimise imports automatically
  • Support HOC like React.memo()
  • Better system for managing 'body' logic. Currently it's just a big string, but there is surely a better way to do this.

About

A format for storing JSX Files as JSON

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages