I have been using these little WiFi boards a lot lately.
So, for the programmer, you can build a simple one. I made one from these instructions and it works GREAT!
Im using level shifters, picked up off e-bay for $1.20 each and ordered 10. They are handy to have available. From what I have read the ESP8233 TX line can go directly to the arduino RX line without a problem. It is the Arduino TX line that needs to be level shifted. It can be done with a resistor based voltage divider in a pinch.
Now for the fun stuff that does not seem to be documented well.
I tried the three libraries I found for it,
#1) used a lot of memory on the device. Digging into it, they were using Strings for everything.
#2) did not work at all, it would not initalize the unit correctly and when digging into it I could not figure out what they were trying to do.
#3) Had issues with memory leaks and kept reseting the unit after every call.
The current AT firmware for it is v0.21 and I am having a lot of issues getting it to work with any of the code above. The same with code I wrote for it. It accepts and responds to the first connection then stops responding.
The older version of the firmware code v0.20 has a bug in it. If it receives a specific auth packet on the wifi network it will stop sending and responding to arp. Seems to freeze for about 5 min.
I have run into issues with the SoftSerial lib that comes with the IDE as well. Ended up using the AltSoftSerial library which fixed a lot of small issues with garbaged data coming in from the unit at 9600.
Dont know if this will help, but here is the frame work that wrote to communicate with the unit. I am always open to suggestions as to how to improve the code. I am still new to Arduino programing. 
#include <AltSoftSerial.h>
/*
bool send_html(char *html, int conid) Sends the HTML contained in *html to the listed connection ID
bool Close_Connection(int conid) Closes the Connection at Connection ID
bool reset() Sends a reset to the unit
bool Join_AP(char ssid[50], char passwd[50]) Joins the AP with the given SSID and Password
bool WifiMode(int mode) Sets the Wifi Mode 1=STA 2=AP 3=Both
bool set_mux(int mux) Sets the MUX 0=single conneciton 1=multi Connection
bool start_server(int mode, int port) Set up the server on the given port mode:0=close, 1=open
void WhatsMyIP() Sets a global variable called MyIP to the IP Address that the unit is listening on.
ESP8266 Firmware must me AT-0942.bin
*/
// Activate Debug mode to the hardware serial.
//#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINTLN(x) Serial.println (x)
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_BEGIN(x) Serial.begin (x)
#else
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINT(x)
#define DEBUG_BEGIN(x)
#endif
AltSoftSerial esp8266; //pin 8 and 9
char MyIP[20];
void setup() {
DEBUG_BEGIN(19200);
esp8266.begin(9600);
DEBUG_PRINTLN(F("Reseting unit"));
if (!reset()) DEBUG_PRINTLN(F("FAILED"));
DEBUG_PRINTLN(F("Setting WiFi Mode"));
if (!WifiMode(1)) DEBUG_PRINTLN(F("FAILED"));
DEBUG_PRINTLN(F("Joining AP"));
if (!Join_AP("MY-SSID", "MY-PASSWORD")) DEBUG_PRINTLN(F("Failed"));
DEBUG_PRINTLN(F("Getting IP Address"));
WhatsMyIP();
DEBUG_PRINT(F("My IP Address is "));
DEBUG_PRINTLN(MyIP);
DEBUG_PRINTLN(F("Setting MUX"));
if (!set_mux(1)) DEBUG_PRINTLN(F("FAILED"));
DEBUG_PRINTLN(F("Starting Server on Port 80"));
if (!start_server(1, 80)) DEBUG_PRINTLN(F("FAILED"));
}
void loop() {
// put your main code here, to run repeatedly:
webpage();
}
void webpage()
{
char tdr[101];
char page[5];
if (esp8266.available()) // check if the esp is sending a message
{
if (esp8266.find("+IPD,"))
{
DEBUG_PRINTLN(F("Found +IPD"));
delay(1000);
int connectionId = esp8266.read() - 48; // subtract 48 because the read() function returns
// the ASCII decimal value and 0 (the first decimal number) starts at 48
if (esp8266.find("GET ")) {
esp8266.readBytesUntil(' ', page, 4);
if ( strstr(page, "/api") ) {
while ( esp8266.read() != -1 );
DEBUG_PRINTLN(F("Sending JSON"));
//Put JSON output here
} else {
while ( esp8266.read() != -1 );
DEBUG_PRINTLN(F("Sending WebPage"));
//Put WebPage Output HERE
DEBUG_PRINTLN(F("Closing Connection"));
if (!Close_Connection(connectionId)) DEBUG_PRINTLN(F("Failed!"));
}
}
}
}
}
bool send_html(char *html, int conid)
{
char cipSend[25];
snprintf(cipSend, 25, "AT+CIPSEND=%i,%i\r\n", conid, strlen(html));
esp8266.println(cipSend);
delay (1000);
if (esp8266.find(">")) {
esp8266.println(html);
}
delay (1000);
return esp8266.find("OK");
}
bool Close_Connection(int conid) {
char cipSend[25];
snprintf(cipSend, 25, "AT+CIPCLOSE=%i\r\n", conid);
esp8266.println(cipSend);
delay(500);
return esp8266.find("OK");
}
bool reset() {
esp8266.println(PSTR("AT+RST\r\n"));
delay(1000);
return esp8266.find("ready");
}
bool Join_AP(char ssid[50], char passwd[50]) {
char cwjap[101];
snprintf(cwjap, 100, "AT+CWJAP=\"%s\",\"%s\"", ssid, passwd);
esp8266.println(cwjap);
delay(4000);
return esp8266.find("OK");
}
bool WifiMode(int mode) {
char cwmode[14];
snprintf(cwmode, 14, "AT+CWMODE=%d\r\n", mode);
esp8266.println(cwmode);
delay(1000);
return esp8266.find("OK");
}
bool set_mux(int mux) {
char cipmux[14];
snprintf(cipmux, 14, "AT+CIPMUX=%d\r\n", mux);
esp8266.println(cipmux);
delay(1000);
return esp8266.find("OK");
}
bool start_server(int mode, int port) {
char server[19];
snprintf(server, 19, "AT+CIPSERVER=%d,%d\r\n", mode, port);
esp8266.println(server);
delay(1000);
return esp8266.find("OK");
}
void WhatsMyIP() {
char incoming;
int ndx = 0;
esp8266.println(PSTR("AT+CIFSR\r\n"));
delay(1000);
esp8266.find("+CIFSR:STAIP,\"");
esp8266.readBytesUntil('\"', MyIP, 18);
}
Here is what I have going so far, the php page does a JSON call to the unit to get the data.
http://xganon.com/temp.php
If you dont get the temp/humidity information on the page, give it 5 min and try again. It hit the problem mentioned earlier.