Hand-written vs Blackbox vs Direct-edit
Both Blackbox and Direct Edit schemes have roughly similar expressivity, and much of the decision of which to use comes down to preference. Here we compare both schemes with each other and with a “vanilla” hand-written approach (what you might write if not using Plasmic), within the context of a concrete example.

Motivating example

As an example, consider a ProfileCard component that displays a user profile in a card-like UI, and allows the current user to follow or unfollow.  It may also optionally display labels associated with the user.  If the user allows contact via email, it also optionally displays the email address and a “Send email” button.  Lastly, if you are already following the user, the card looks blue.

You can take a look at the Profile Cards project here; feel free to make a copy for yourself so you can play with it.

Hand-written React component

A hand-written React component might look something like this:

// {tsx}
function ProfileCard(props) {
  const {user, isFollowing, dispatch} = props;
  return (
    <div 
      className=`profilecard ${isFollowing ? "profilecard--following" : ""}`
      onMouseEnter={() => dispatch("focusUser", user.id)}
      onMouseLeave={() => dispatch("focusUser", undefined)}
    >
      <Draggable>
        <div className="profilecard__avatar">
          <img className="profilecard__user_pic" src={user.image} />
          <span className="profilecard__user_name">{user.username}</span>
        </div>
      </Draggable>
      <div className="profilecard__content">
        <div className="profilecard__full_name">
          {user.fullname}
        </div>
        {user.email && user.allowContact &&
          <div className="profilecard__email">{user.email}</div>
        }
        {user.labels &&
          <div className="profilecard__labels">
            <div className="profilecard__labels_header">Labels:</div>
            <ul className="profilecard__labels_container">
              {user.labels.map(tag => <li className="profilecard__label">{label}</li>)}
            </ul>
          </div>
        }
        <div className="profilecard__actions">
          <Button
            className="btn btn--small"
            type={isFollowing ? "secondary" : "primary"}
            onClick={() => dispatch(isFollowing ? "unfollow" : "follow", user.id)}
          >
            {isFollowing ? "Unfollow" : "Follow"}
          </Button>
          {user.email && (
            <Button