CCK exists of the following things for me : 1. Field Types 2. widgets and formatters 3. Data model - consisting of the field types. 4. Query builder - crud functions. - generates query from data model. 5. Configuration interface - builds data model I believe that we should integrate 1-3 into the forms api (and indeed create the data api that way). All the field types that cck has, (ie: integers, floats, etc) have validations already. Which is already much much stronger than what we have currently (using textfields for everything. pfft). Form elements as we have them now, are essentially widgets as CCK has them. Every field type has a default widget it uses. This is an extra (optional) property of the form array. So everywhere we have $form['title'] = array('#type' => 'textfield'); we will then have : $form['title'] = array('#type' => 'text'); I don't believe we should make a differentiation for widgets / formatters. They are just input/display widgets. All field types, have a default widget for editing, and for display. These can be overridden in the fapi array. I see that as a first phase, which would bring all the field type / widget code into core.. and all forms will re-use the same code. Including profiles. Second phase : data model. --- As I specified in my data model presentation at the last DrupalCon, we have a data model currently, it's just hidden in the form array structure. We use an incredible amount of complex logic to try and determine the data model from the form array. Just about all the complexity in form_builder comes from this process. CCK does this the right way around, it creates a data model (by defining the fields) and then converts the data model into a form / display. For consistency, we should then look at making all forms use the same mechanism. This will _greatly_ simplify the amount of twiddling we need to do in form_builder. The form / view is actually a superstructure built on top of the data model, with added display / form specific properties added. In my example, they took the form of a data model function, which defines only the fields: function model_objecttype() { // these constructor functions return arrays with all the default values for that type already populated. // this improves cacheability, in that all the array merging is done in the first step, not recursively called on everything. // it also lessens the amount of code needed, and imo improves readability. $model['id'] = drupal_field('id'); // defaults to edit_widget => hidden $model['title'] = drupal_field('title'); // Additional default field lengths , and defaults to a textfield. $model['body'] = drupal_field('body'); return $model; } This can then be turned into a view / form : function form_objecttype($model) { $form['id'] = drupal_widget($model['id']); $form['fieldset'] = drupal_widget('fieldset', array('title' => 'something') ); $form['fieldset']['title'] = drupal_widget($model['title'], array ('widget' => 'textarea') ); $form['fieldset']['body'] = drupal_widget($model['body'], array ('widget' => 'textfield')); return $form; } By just automatically recurring through the model data structure, we can change it into a form without even needing to have a separate function (the same way we can do drupal_render without needing to specify a theme function). Other things that will get added into the display, is stuff like tables. At this point, we have got the Data API as i mentioned created. After this we can look at making the CRUD functions (which imo shouild be standardised into save_objecttype, create_objecttype, delete_objecttype, load_objecttype) work with a query builder, as it does for cck.